当前位置: 首页 > 知识库问答 >
问题:

最大和子数组O(n)not Kadane

金令
2023-03-14

现在我用不同的测试场景测试它,总是比Kadena的结果更好。我不相信这样的运气,但找不到我错过了什么。你能看看这是否是一个有效的解决方案吗?

public void findMaxSubarray(Number[] numbers) {
    int maxSum = Integer.MIN_VALUE;
    int left = 0;
    int right = numbers.length - 1;

    int i = 0;
    int j = i + 1;
    int sum = numbers[i].intValue();

    while (i < numbers.length) {
        if (maxSum < sum) {
            maxSum = sum;
            left = i;
            right = j - 1;
        }
        if (j >= numbers.length)
            return;
        sum = sum + numbers[j].intValue();
        if (sum <= 0) {
            // ignoring "first" negative numbers. shift i to first non-negative
            while (numbers[j].intValue() <= 0) {
                if (maxSum < numbers[j].intValue()) {
                    maxSum = numbers[j].intValue();
                    left = j;
                    right = j;
                }
                if (++j >= numbers.length)
                    return;
            }
            i = ++j;
            sum = 0;
        }
        j++;
    }
    System.out.println(String.format("Max subarray is %d, [%d; %d]", maxSum, left, right));
}

更新代码的思想是只跟踪一个子数组,并添加到其尾数,当数字很低时,和成为尾数组后的负集开始。另外,一开始的负面项目被忽略了。子数组的头只是向前移动。每次sum看起来是maximal-maxsum并且限制被更新。

shift i() --to first non negative number
from j = i+1 up to N.length
  sum + N[j]
  if sum <= 0
    i = j+1
    if N[i] < 0
      shift i()
    sum = 0

共有1个答案

汪信鸥
2023-03-14

我认为你的算法基本上是健全的,但它有两个bug我可以看到:

  1. 在输入1-2103时,它将跳过10并输出3。我认为可以通过将I=++j;更改为I=j;.
  2. 来解决这个问题
  3. 在两个不同的地方返回,如果j超过末尾,这将导致根本不产生输出!(例如,如果列表末尾出现一长串负数,就会发生这种情况。)

我也不希望它比卡丹的更快(或更慢,就此而言)。两个数的求和是一个快速的操作,就像将一个变量复制到另一个变量一样快,当您移动子数组的开始时,这就是您正在做的。

 类似资料:
  • null 在一个视频教程中,作者提到暴力方法是,阅读另一个答案,一个人认为是,另一个人认为是 强力是还是?更重要的是,您能说明您对蛮力方法执行了哪些分析以知道它是吗?

  • 我试图在一个数组中找到具有最大和的邻接子数组。所以,对于数组 {5,15,-30,10,-5,40,10}

  • 例如:{1,2,3,4,-3}输出将是4,因为1+2+3+4的和是最大和,该序列中有4个数字 我知道如何用O(n^2)的时间复杂度来做这件事,但不知道如何用O(n)的帮助?:)

  • 很抱歉发了这么长的帖子,但我不明白我做错了什么。感谢您事先的帮助! 这里是当前面提到的列表作为输入给出时的输出,我已经经历并查看了每一个步骤,列表中的每一个消除在我看来都是合乎逻辑的,我不知道一个人怎么会以结束和105结束。如果有人能帮我理解,我会非常感激的!

  • 给出了一个由N个整数组成的数组。 数组的最大和是该数组的非空连续子数组的元素的最大和。 例如,数组[1,-2,3,-2,5]的最大和是6,因为子数组[3,-2,5]的和是6,并且不可能实现更大的子数组和。 现在,您只能从给定数组中删除一个以上的元素。这样做可以得到的结果数组的最大可能最大和是多少? 我正在用我自己的测试用例测试我的代码。我在Dev-C++上得到了正确的输出。但是当我在网上测试我的代

  • 我的看法是: 改变符号并在其中找到最大和,与我们计算最大和子数组的方法相同。改变数组中元素的符号使其处于初始状态。 如果algo有任何问题,请帮助我更正。 拐角情况:我知道如果所有元素都是正的就会有问题,我们可以通过做一些预处理来处理这种情况,即如果所有元素都是+Ve,就遍历数组,而不仅仅是从数组返回最小值。 上面提到的算法将工作,并得到DasBlinkenlight的良好支持(解释)。