leetcode 1658

本文介绍了如何通过滑动窗口解决寻找数组中和为目标值的子序列问题。从最初的贪心算法尝试,到发现其局限性,再到采用滑动窗口方法进行优化。详细阐述了滑动窗口思路,包括如何维护窗口内的和以及移动边界条件。最后,给出了具体的Java代码实现,并讨论了代码中可能遇到的陷阱和解决方案。
摘要由CSDN通过智能技术生成

这题一开始试图用贪心,我用两个指针分别指向头和尾,然后每次选较大的值,移动指针,直到和加起来=x,但是如果两个值相等,该如何移动?就不行了。DP也考虑过,时间复杂度较高。

然后换一种思路,在原数组两端找两个子数组和=x,等同于在原数组中间找一个连续的子数组和=原数组和-x。这样就可以用滑动窗口了,sum表示原数组总和,用midSum记录中间数组的和,每次循环先移动右边界,如果midSum>sum-x,且right>=left,则一直左移left;这里right>=lefth很重要,我一开始漏掉了right=left的情况,这时候left左移之后=right+1,midSum=0。每轮循环最后,如果left不再需要左移了,判断midSum==sum-x,相等则更新答案。我初始化ans为int最大值,每次更新保留最小值,如果最终ans没有被更新过,那么就是没找到,返回-1。

class Solution {
     public int minOperations(int[] nums, int x) {
        int ans = Integer.MAX_VALUE;
        int sum = 0;
        for (int n : nums) {
            sum += n;
        }
        int midSum = 0;
        for (int left = 0, right = 0; right < nums.length; right++) {
            midSum += nums[right];
            while (midSum > sum - x && right >= left) {
                midSum -= nums[left++];
            }
            if (midSum == sum - x) {
                ans = Math.min(ans, nums.length - (right - left + 1));
            }
        }
        return ans == Integer.MAX_VALUE ? -1 : ans;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值