该题型多采用prefixSum的方法:
(一)Maximum Subarray (Frequent ++)
https://leetcode.com/problems/maximum-subarray/description/
题目:找到数组中总和最大的子集并返回该子集总和;
解答:从头到尾依次遍历数组,实时记录最大的sum值和最小的sum值。每次只需比较当前最大值和当前sum-最小sum的值,即可更新最大sum值。
改进:可以把求prefixSum的循环和找最大的循环合并成一个
代码:
class Solution {
public int maxSubArray(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int max = Integer.MIN_VALUE;
int sum = 0;
int minSum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
max = (sum - minSum) > max ? (sum - minSum) : max;
minSum = sum < minSum ? sum : minSum;
}
return max;
}
}
public int subarraySum(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return 0;
}
int res = 0;
for (int i = 1; i < nums.length; i++) {
nums[i] += nums[i - 1];
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] == k) {
res++;
}
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] - nums[i] == k) {
res++;
}
}
}
return res;
}
}
/**
* @param nums: A list of integers
* @return: A list of integers includes the index of the first number
* and the index of the last number
*/
public int[] subarraySumClosest(int[] nums) {
// write your code here
int[] res = new int[2];
int[] prefixSum = new int[nums.length + 1];
int diff = Integer.MAX_VALUE;
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
prefixSum[i + 1] = prefixSum[i] + nums[i];
if (!map.containsKey(prefixSum[i])) {
map.put(prefixSum[i], i);
} else {
res[0] = map.get(prefixSum[i]);
res[1] = i - 1;
return res;
}
}
if (!map.containsKey(prefixSum[nums.length])) {
map.put(prefixSum[nums.length], nums.length);
} else {
res[0] = map.get(prefixSum[nums.length]);
res[1] = nums.length - 1;
return res;
}
Arrays.sort(prefixSum);
for (int i = 1; i < nums.length + 1; i++) {
if (prefixSum[i] - prefixSum[i - 1] < diff) {
int i1 = map.get(prefixSum[i]);
int i2 = map.get(prefixSum[i - 1]);
diff = prefixSum[i] - prefixSum[i - 1];
res[0] = Math.min(i1, i2);
res[1] = Math.max(i1, i2) - 1;
}
}
return res;
}
}