最大子数组的特殊情况

Posted

技术标签:

【中文标题】最大子数组的特殊情况【英文标题】:Special case in maximum subarray 【发布时间】:2019-07-21 03:09:27 【问题描述】:

我使用分而治之来解决最大子数组问题。 它在最常见的情况下工作正常,但在特殊情况下失败。 我认为问题可能发生在这里:

struct subarray maximum_crossing(int A[], int low, int mid ,int high)
    int left_sum = INT_MIN;
    int left_max = mid;
    int sum = 0;
    for (int i=mid; i >= low; i--)
        sum += A[i];
        if (sum > left_sum)
            left_sum = sum;
            left_max = i;
        ;
    ;
    ..........
    ..........

我对其进行了测试,它在常见情况下确实运行良好。 但是当数组看起来像这样时:-2147483648,-2147483648,-2147483648,它将返回从 0 开始到 1 结束的最大子数组,并且最大和为 0。我认为这是因为 INT_MIN + INT_MIN 将是0 在 C 中。

或者在-2147483648, -1, 0中,代码会发现最大子数组从0开始,以1结束,最大和为2147483648。由于这个问题,一旦数组有-2147483648和其他负数值,代码将不起作用。

我尝试使用 if 语句首先检查 A[i] 的值,但我发现这不是最佳解决方案。因为其他负值加起来仍然可以超过-2147483648。那么有没有更合适的方法来解决这种情况呢?

【问题讨论】:

您可以使用A[i] > 0作为条件,然后才执行增量。 但是如果我设置这个条件,在整个数组为负数的情况下,代码会返回错误的答案。 sum += A[i]; 肯定溢出了。试试long long left_sum = INT_MIN; long long sum = 0; 还是不行。我在我的电脑上检查了长长的INT_MIN的值仍然是-2147483648。 【参考方案1】:

最大总和为 2147483648

2147483648(十进制)是 2^31,如果你的 int 是 32 位 2147483648 对有符号 int 溢出,所以max_sum 不能是 2147483648

sumleft_sum 使用long(假设在64b)

【讨论】:

我尝试使用 long 和 long long ,看来我的电脑只能让值不超过-2147483648。 警告使用后缀 'l' 来强制字面值是长整数,否则为整数,例如 2147483648l 而不是 2147483648。如果您对 longlong longsizeof 有疑问,只需在代码中添加一个 printf 即可打印他们的 sizeof 非常感谢!这行得通 !结果我忘了更改存储最终结果的其他变量。

以上是关于最大子数组的特殊情况的主要内容,如果未能解决你的问题,请参考以下文章

算法设计--在数组中找求和最大的连续子串

2021-10-18:乘积最大子数组。给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。力扣152。

数组之求最大子数组之和

二维数组最大子数组(结对开发)

二维数组最大子数组(结对开发)

最大子数组三