给你一个整数数组 nums
和一个整数 x
。每一次操作时,你应当移除数组 nums
最左边或最右边的元素,然后从 x
中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x
恰好 减到 0
,返回 最小操作数 ;否则,返回 -1
。
示例 1:
输入:nums = [1,1,4,2,3], x = 5 输出:2 解释:最佳解决方案是移除后两个元素,将 x 减到 0 。
BFS,超时
class Solution {
public int minOperations(int[] nums, int x) {
int a= helper(nums, x, 0, nums.length - 1);
return a == Integer.MAX_VALUE ? -1 : a;
}
private int helper(int[] nums, int x, int left, int right) {
if(x == 0) return 0;
if(x < 0) return Integer.MAX_VALUE;
if(left > right) return Integer.MAX_VALUE;
int a = nums[left];
int b = nums[right];
int t1 = helper(nums, x - a, left + 1, right);
int t2 = helper(nums, x - b, left, right - 1);
if(t1 != Integer.MAX_VALUE) t1 = t1 + 1;
if(t2 != Integer.MAX_VALUE) t2 = t2 + 1;
return Math.min(t1, t2);
}
}
可以考虑前缀+Hashmap,从结果的角度分析,最终结果形态肯定是左侧取n个元素,右侧取m个元素。那么计算过程中,可以忽略掉单测元素的顺序。则可以反向记录所有右侧元素的sum并放入map,value是次数。
在从左便利,计算取到左侧k元素后,map中的右侧sum是否可以满足x=0.可以的话,即为答案
以下为参考leetcode他人答案
class Solution {
public int minOperations(int[] nums, int x) {
int n = nums.length;
int[] sum = new int[n + 1];
Map<Integer, Integer> map = new HashMap<>();
sum[n - 1] = nums[n - 1];
int ans = n + 1;
map.put(0, 0);
for (int i = n - 1; i >= 0; i--) {
sum[i] = sum[i + 1] + nums[i];
if (sum[i] == x)
ans = Math.min(ans, n - i);
map.put(sum[i], n - i);
}
for (int i = 0; i < n; i++) {
x -= nums[i];
if (map.containsKey(x))
ans = Math.min(ans, i + 1 + map.get(x));
}
return ans == n + 1 ? -1 : ans;
}
}