327. 区间和的个数
327. 区间和的个数
问题
给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper。
区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。
说明:
最直观的算法复杂度是 O(n2) ,请在此基础上优化你的算法。
示例:
输入: nums = [-2,5,-1], lower = -2, upper = 2,
输出: 3
解释: 3个区间分别是: [0,0], [2,2], [0,2],它们表示的和分别为: -2, -1, 2。
分析
- 首先可以想到二次方的暴力解法;
- 接着有了前缀和的灵感;
- 然后就是想对前缀和数组排序看看能不能直接解决问题(并不能,因为只有长的前缀和减掉短的前缀和才能和边界比较,排序后的前缀和数组做差可能会出现相反数);
- 为了解决第三步的问题,可以在一层循环中,边排序,边统计结果;
- 总结以上特点,我们要对不改变原来前缀和的元素:边统计边排序,而具体的统计方式是对于前缀和数组preSum,lower <= preSum[j] - preSum[i] <= upper (i < j) 的时候更新res;
- 不改变原数组元素相对位置的前提下,边比较,边更新排序,想到了归并排序算法;
- 只需要在Merge函数排序前进行统计就可以了,同时,Merge统计的只是两个前缀和做差的区间,并没有考虑前缀和区间本身,因此在创建preSum的时候,要对preSum[i] (0 <= i <= preSum.length - 1) 单独做一次统计;
1 |
|