给定一个整数数组 nums[] 和一个整数 x。在每一次操作中,我们都可以从数组 nums 的最左端或最右端移除一个元素,并从 x 中减去该元素的值。请注意,这会修改数组,并影响后续的操作。本任务的目标是返回将 x 减至恰好 0 所需的最少操作次数;如果无法实现,则返回 -1。
示例:
> 输入: nums = [1,1,4,2,3], x = 5
> 输出: 2
> 解释: 最优的方案是移除最后两个元素,从而将 x 减为零。
>
>
>
> 输入: nums = [5,6,7,8,9], x = 4
> 输出: -1
> 解释: 没有任何方法可以将 x 减为零。
方法: 要解决这个问题,我们可以遵循以下思路:
> 为了以最少的移动次数将 x 减为零,我们可以换一种说法:找到一个总和等于 (总和 – x) 的最大子数组。
下面让我们详细解释一下这种方法的具体步骤:
- 首先,计算 nums 向量中所有元素的总和,并将其存储在变量 totsum 中。
- 检查 totsum 是否等于 x。如果相等,直接返回 nums 向量的大小,因为总和本身就已经等于 x 了(即移除所有元素)。
- 计算 totsum 和 x 之间的差值,并将这个差值重新存入 totsum 变量。这个值代表了我们需要通过从向量两端移除元素,从而在数组中间保留下来的“目标子数组和”。
- 初始化两个指针 s 和 e,并将其设为 0。这两个指针代表了我们当前考虑的子数组的起始和结束位置。
- 初始化变量 sum 和 ans 为 0。sum 变量将跟踪当前子数组的和,而 ans 将存储找到的满足条件的子数组的最大长度。
- 使用一个以 e 指针为条件的 while 循环来遍历 nums 向量中的元素。
- 将索引 e 处的元素加到 sum 中。
- 使用另一个以 s 指针为条件的 while 循环来调整子数组,即从子数组的起始位置移除元素,直到 sum 小于或等于 totsum。
- 检查 sum 是否等于 totsum。如果是,则更新 ans ,记录目前找到的最长子数组长度(e – s + 1)。
- 增加 e 指针的值,以考虑数组中的下一个元素。
- 最后,返回结果:如果 ans 仍然为 0,则返回 -1(表示无法通过操作使 x 变为 0),否则返回 nums.size() – ans,这代表了实现目标所需的最少操作次数。
下面是上述方法的实现代码:
// C++ Code for the above approach:
#include
using namespace std;
class Solution {
public:
int minOperations(vector& nums, int x)
{
int n = nums.size();
int totalS = 0;
// Calculate the total sum of the
// elements in the vector ‘nums‘
for (int i = 0; i < n; i++) {
totalS += nums[i];
}
// If the total sum is equal to 'x',
// no operations are needed
if (totalS == x) {
return n;
}
// Calculate the difference between
// the total sum and 'x'
totalS = totalS - x;
int i = 0;
int j = 0;
int sum = 0;
int ans = 0;
// Sliding window approach to find
// the minimum operations
while (j < n) {
sum += nums[j];
// If the current sum is greater
// than the target difference, move
// the window's left end (i) to
// reduce the sum
while (i totalS) {
sum -= nums[i];
i++;
}
// If the current sum equals the
// target difference, update the
// answer with the maximum
// window size
if (sum == totalS) {
ans = max(ans, j - i + 1);
}
j++;
}
// If ‘ans‘ is still 0, it means no
// subarray with the target sum was found
return ans == 0 ? -1 : n - ans;
}
};
// Drivers code
int main()
{
Solution solution;
vector nums = { 1, 1, 4, 2, 3 };
int x = 5;
int result = solution.minOperations(nums, x);
if (result == -1) {
cout << "No solution found." << endl;
}
else {
cout << "Minimum operations required: " << result
<< endl;
}
return 0;
}
“`java
// Java code for the above approach
import java.util.*;
public class Solution {
public int minOperations(int[] nums, int x)
{
int n = nums.length;
int totalSum = 0;
// Calculate the total sum of the elements in the
// array ‘nums‘
for (int i = 0; i < n; i++) {
totalSum += nums[i];