最大子数组的特殊情况
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
对sum
和left_sum
使用long(假设在64b)
【讨论】:
我尝试使用 long 和 long long ,看来我的电脑只能让值不超过-2147483648。 警告使用后缀 'l' 来强制字面值是长整数,否则为整数,例如2147483648l
而不是 2147483648
。如果您对 long 和 long long 的 sizeof 有疑问,只需在代码中添加一个 printf 即可打印他们的 sizeof
非常感谢!这行得通 !结果我忘了更改存储最终结果的其他变量。以上是关于最大子数组的特殊情况的主要内容,如果未能解决你的问题,请参考以下文章
2021-10-18:乘积最大子数组。给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。力扣152。