最大和子数组

时间:2018-01-09 20:36:34

标签: arrays python-3.x algorithm data-structures dynamic-programming

我想在复杂度O(n)O(1)中推导出一种方法,我可以在重复k次时找出子数组的最大总和。

假设我有一个数组a=[-5,2,2,2],其最大子数值为6,现在当我再次重复同一个数组a=[-5,2,2,2,-5,2,2,2]时,最大子数组值为7

当我在问题中重复这个数组k次时,我想要一种通用的方法。

所以,任何人都可以指导我用他们的解决方案解决这个问题的方法。更多的事情我只懂python语言所以请任何人帮助我

3 个答案:

答案 0 :(得分:2)

计算包含最右边元素的子串的最高和,并将其称为sumR。然后使用最左边的元素执行相同的操作并将其命名为sumL。然后计算整个数组的总和并称之为sumT。最后,计算没有迭代的子串的最高总和,并将其称为sumS

现在,在重复k次的情况下,我们最多有三个候选人:sumSsumL+sumRsumR+(k-1)*sumT+sumL

然而,有一个问题。如果sumLsumR小于零,则无效。所以我们计算sumLong = (k-t)*sumT + max(0, sumR) + max(0, sumL)

现在有三种可能的候选人:

  • sumS如果最大值在寄宿生内。示例:[-10,2,3,-9]
  • sumL+sumR如果最大值恰好是一次重复。示例:[1,-10,1]
  • sumLong如果最大值包含完整重复:[2,3,4]

注意哪个候选者是真正的最大值不仅取决于数组。它还取决于k的值。我列出的示例是不依赖于k的数组。

根据维基百科,在O(n)中计算sumS很容易,并且因为所有其他计算甚至更简单并且只需要进行一次,所以它是O(n)总数。这是代码:

def max_subarray(A):
# https://en.wikipedia.org/wiki/Maximum_subarray_problem#Kadane%27s_algorithm_(Algorithm_3:_Dynamic_Programming)
    max_ending_here = max_so_far = A[0]
    for x in A[1:]:
        max_ending_here = max(x, max_ending_here + x)
        max_so_far = max(max_so_far, max_ending_here)
    return max_so_far

def maxR(A):
    cm = sum_so_far = A[-1]
    for i in range(0, len(A)-1)[::-1]:
        sum_so_far = sum_so_far + A[i]
        cm = max(cm, sum_so_far)
    return cm

def maxL(A):
    cm = sum_so_far = A[0]
    for i in range(1, len(A)):
        sum_so_far = sum_so_far + A[i]
        cm = max(cm, sum_so_far)
    return cm

def max_subarray_rep(A,k):
    sumS=max_subarray(A)
    if(k<1):
        return sumS
    sumL=maxL(A)
    sumR=maxR(A)
    if(k==1):
        return max(sumS, sumR+sumL)
    sumT=sum(A)
    sumLong = (k-1)*sumT + max(0, sumL) + max(0, sumR)
    return max(sumLong, sumR+sumL, sumS)

max_subarray_rep包含一些冗余行,但这些行是出于教育目的,以便更容易理解背后的想法。

在O(1)中执行此操作是不可能的。我也愿意赌很多钱,不可能低于O(n)。

答案 1 :(得分:0)

在最常见的情况下,您可以在O(n)中计算最大子阵列:

def max_subarray(A):
    solve = A[0]
    sum = 0
    for i in range(0, len(A)):
         sum = sum + A[i]
         if sum > solve:
               solve = sum
         if sum < 0:
               sum = 0
     return solve

答案 2 :(得分:0)

这是解决我所有测试用例的解决方案。如果包含任何错误或限制,请予以纠正。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;


public class Main {
    private JFrame frame = new JFrame();
    private JLayeredPane lpane = new JLayeredPane();
    private JPanel panelBlue = new JPanel();
    private JPanel panelGreen = new JPanel();
    private JButton btn1 = new JButton ("Button1");

    public Main()
    {
        frame.setPreferredSize(new Dimension(600, 400));
        frame.setLayout(new BorderLayout());
        frame.add(lpane, BorderLayout.CENTER);
        lpane.setBounds(0, 0, 600, 400);
        panelBlue.setBackground(Color.BLUE);
        panelBlue.setBounds(0, 0, 600, 400);
        panelBlue.setOpaque(true);
        panelBlue.add (btn1);

        panelGreen.setBackground(Color.GREEN);
        panelGreen.setBounds(200, 100, 100, 100);
        panelGreen.setOpaque(true);


        btn1.addActionListener(new ActionListener () {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                panelGreen.add(new JLabel ("You click button1"));


            }});



        lpane.add(panelBlue, new Integer(0), 0);
        lpane.add(panelGreen, new Integer(1), 0);
        frame.pack();
        frame.setVisible(true);
    }


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main();
    }
}