我想在复杂度O(n)
或O(1)
中推导出一种方法,我可以在重复k
次时找出子数组的最大总和。
假设我有一个数组a=[-5,2,2,2]
,其最大子数值为6
,现在当我再次重复同一个数组a=[-5,2,2,2,-5,2,2,2]
时,最大子数组值为7
。
当我在问题中重复这个数组k次时,我想要一种通用的方法。
所以,任何人都可以指导我用他们的解决方案解决这个问题的方法。更多的事情我只懂python
语言所以请任何人帮助我
答案 0 :(得分:2)
计算包含最右边元素的子串的最高和,并将其称为sumR
。然后使用最左边的元素执行相同的操作并将其命名为sumL
。然后计算整个数组的总和并称之为sumT。最后,计算没有迭代的子串的最高总和,并将其称为sumS
。
现在,在重复k
次的情况下,我们最多有三个候选人:sumS
,sumL+sumR
和sumR+(k-1)*sumT+sumL
然而,有一个问题。如果sumL
或sumR
小于零,则无效。所以我们计算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();
}
}