剑指offer 专项突破版 8、和大于等于 target 的最短子数组

题目链接

思路:可以采用滑动窗口的方法,遍历一遍就找到最终的值,我们最初让left和right都指向第一个值,同时维护一个sum,表示left和right之间所有数字的和,每次循环让right递增,然后sum对应增加。如果此时sum>=target,那就让left–,同时更新sum和result,直到sum < target

复杂度分析

  • 时间复杂度:左右指针各遍历了一遍数组,所以是O(n)
  • 空间复杂度:O(1)
public int minSubArrayLen(int target, int[] nums) {
        int result = Integer.MAX_VALUE, left = 0, right = 0, sum = 0;

        for (right = 0; right < nums.length; right++) {

            sum += nums[right];
            while (sum >= target && left <= right) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left++];
            }
        }

        return Integer.MAX_VALUE == result ? 0 : result;
    }

Go版本

func minSubArrayLen(target int, nums []int) int {
	left, right, sum := 0, 0, 0
	result := math.MaxInt

	for right < len(nums) {
		sum += nums[right]
		// 通过不断更新left来找到此时最短的长度
		// 可以不用增加条件left <= right,因为极端条件为left=right,然后此时的nums[left] > target
		// 这时循环结束后left=right+1 且 sum=0,循环会结束,然后right又+1,这样right和left就相等了
		for sum >= target {
			result = min(result, right-left+1)
			sum -= nums[left]
			left++
		}
		right++
	}
	if result == math.MaxInt {
		return 0
	}
	return result
}

func min(x, y int) int {
	if x > y {
		return y
	}
	return x
}

注意外层循环更新右指针,内循环更新左指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值