【专题:数组】【LeetCode】209. 长度最小的子数组

161 阅读1分钟

长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例1

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例2

输入:target = 4, nums = [1,4,4]
输出:1

示例3

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

思路

  • 本题和上题类似,使用滑动窗口来维持“长度最小的连续子数组”。
  • 定义两个指针left,right,若当前的数组和大于等于target,则保存当前子数组的长度,并且将左指针的元素去除,左指针右移;若当前的数组和小于target,则sum和right指向的元素相加,并ritght右移。

解法一

func minSubArrayLen(target int, nums []int) int {
    left,right:=0,0
    minValue:=len(nums)+1
    sum:=0
    allSum:=0
    for _,v:=range nums{
        allSum=allSum+v
    }
    if allSum<target{
        return 0
    }

    for right<len(nums){
        if  sum<target{ // 若当前的数组和小于target
            sum=sum+nums[right] // sum和right指向的元素相加
            right++ 
        }
        // 下方使用for循环,是为了避免一种情况出现,当right指向的元素很大,而左边的元素很小的时候,需要删除左边的多个小元素
        for  sum>=target{ // 若当前的数组和大于等于target
            minValue=min(minValue,right-left) // 保存当前子数组的长度
            sum=sum-nums[left] // 将左指针的元素去除
            left++ // 左指针右移
        }
    }
    return minValue
}
func min(a,b int)int{
    if a<b{
        return a
    }
    return b
}

解法二

func minSubArrayLen(target int, nums []int) int {
    left,right:=0,0
    minValue:=len(nums)+1
    sum:=0
    allSum:=0
    for _,v:=range nums{
        allSum=allSum+v
    }
    if allSum<target{
        return 0
    }

    for right<len(nums){
        for  sum<target&&right<len(nums){ // 若当前的数组和小于target
            sum=sum+nums[right] // sum和right指向的元素相加
            right++ // ritght右移
        }
        // 下方使用for循环,是为了避免一种情况出现,当right指向的元素很大,而左边的元素很小的时候,需要删除左边的多个小元素
        for  sum>=target&&left>=0{ // 若当前的数组和大于等于target
            minValue=min(minValue,right-left) // 保存当前子数组的长度
            sum=sum-nums[left] // 将左指针的元素去除
            left++ // 左指针右移
        }
    }
    return minValue
}
func min(a,b int)int{
    if a<b{
        return a
    }
    return b
}

总结:

  • “连续子数组”使用滑动窗口方法。