将数组 X 减至 0 的最小操作次数

给定一个整数数组 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 变量。这个值代表了我们需要通过从向量两端移除元素,从而在数组中间保留下来的“目标子数组和”。
  • 初始化两个指针 se,并将其设为 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];

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/49143.html
点赞
0.00 平均评分 (0% 分数) - 0