1.数组两端向内连续求和的问题 可以转化为 先求出数组元素的总和然后再减去中间子数组(不是子序列)和的问题。注意的是 需要对最左和最右两个元素单独判断
2.对于子数组的和可以使用前缀和方法
本题代码如下,但对于1658来说代码比较复杂,有更简单的写法
/**
* 两边求和等于target的问题==转化==>数组总和sum-中间子数组的和都等于target的问题
*/
class Solution {
public int minOperations(int[] nums, int x) {
if (nums[0] == x || nums[nums.length - 1] == x)
return 1;
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
int target = sum - x;
if (target == 0)
return nums.length;
int res = Integer.MAX_VALUE;
//求前缀和
HashMap<Integer, List<Integer>> map = new HashMap<>();
ArrayList<Integer> first = new ArrayList<>();
first.add(-1);
map.put(0, first);
int[] preSum = new int[nums.length];
preSum[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
preSum[i] = preSum[i - 1] + nums[i];
if (map.containsKey(preSum[i]))
map.get(preSum[i]).add(i);
else {
ArrayList<Integer> list = new ArrayList<>();
list.add(i);
map.put(preSum[i], list);
}
}
for (int i = 0; i < preSum.length; i++) {
List<Integer> list = map.get(preSum[i] - target);
if (list == null)
continue;
for (Integer index : list) {
if (index <= i) {
res = Math.max(res, i - index);
}
}
}
return res == Integer.MAX_VALUE ? -1 : nums.length - res;
}
}