5602. 将 x 减到 0 的最小操作数 双指针

给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。

如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。

示例 1:

输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。
示例 2:

输入:nums = [5,6,7,8,9], x = 4
输出:-1
示例 3:

输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。

提示:

1 <= nums.length <= 105
1 <= nums[i] <= 104
1 <= x <= 109

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-operations-to-reduce-x-to-zero
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

别用搜索方法,会超时
取两边的元素,让他们的和等于x即
对这个数组,求出和sum,有一段区间的和=sum-x
用双指针搜索这个区间,然后特殊判断一下当区间不存在的情况。

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int n = nums.size();
        int target = 0;
        for (auto num : nums) {
            target += num;
        }
        target -= x;

        // 全部选中的情况,即不用l和r去遍历区间
        if (target == 0) {
            return n;
        }
        // 至少有一个元素没被选中的情况,得用l和r去遍历区间
        int l = 0, r = 0;
        int ans = -1;
        int now = nums[l];
        while (l <= r && r < n) {
            if (now == target) {
                cout << l << " " << r << endl;
                ans = max(ans, r - l + 1);
            }
            if (now <= target) {
                now += nums[++r];
            }
            else {
                now -= nums[l++];
            }
        }


        return ans == -1 ? ans : n - ans;

    }
};
posted @ 2020-11-15 13:31  _西瓜不甜  阅读(167)  评论(0编辑  收藏  举报