滑动窗口类算法题

209. 长度最小的子数组

力扣地址数组

暴力破解思路

时间复杂度有点高,O(n3),通不过测试,要进行优化

func minSubArrayLen(s int, nums []int) int {
    length := len(nums)
    min := length + 1
    for i := 0; i< length; i++{
        for j := i; j<length;j++{
            if j-i+1 >=min{
                break //这一趟已经不必找了
            }
            sum := 0
            for k := i;k<=j;k++{
                sum += nums[k]
            }
            if sum >= s{
                min = j-i+1
                break //这一趟已经找到,能够直接返回
            }
        }
    }

    //没有找到知足条件的连续子数组,返回0
    if min == length + 1{
        return 0
    }
    return min
}

暴力破解思路优化1

优化方向:暴力破解第三个for循环其实能够去除的,由于咱们对[i,j]数组求和是一个连续的过程,是一个一个添加元素的,他们知足sum[i,j] = sum[i,j-1] + nums[j].

func minSubArrayLen(s int, nums []int) int {
    length := len(nums)
    min := length + 1
    for i := 0; i< length; i++{
        sum := nums[i]
        for j := i; j<length;j++{
            if j-i+1 >=min{
                break //这一趟已经不必找了
            }
            if j > i{
               sum += nums[j]
            }
            if sum >= s{
                min = j-i+1
                break //这一趟已经找到,能够直接返回
            }
        }
    }

    //没有找到知足条件的连续子数组,返回0
    if min == length + 1{
        return 0
    }
    return min
}

暴力破解思路优化2

优化思路:第二个for循环仍是能够加快点,由于数组和sum[i,j]是有序增长的,因此就想到二分查找的优化方法。

滑动窗口思路

func minSubArrayLen(s int, nums []int) int {
    //滑动窗口的解法:由于题目是一个连续子数组最小问题,知足滑动窗口类型
    length := len(nums)
    l,r := 0,-1 // nums[l,r] 是咱们的一个滑动窗口,默认是没有元素
    sum := 0
    min := length +1 
    for l < length{
        if sum >= s{ //滑动窗口里面和已经知足要求,就不用继续向右滑
            sum -= nums[l]
            l++
        }else if r+1<length{//能够容许右滑
            r++
            sum += nums[r]
        }else{
            break //滑动窗口不能右滑了,找不到,直接返回
        }

        if sum >= s && r-l+1 < min{
            min = r-l+1
        }
    }

    if min == length +1 {
        return 0
    }
    return min
}
  1. 无重复字符的最长子串
  2. Find All Anagrams in a String
  3. 最小覆盖子串 && 76. Minimum Window Substring
相关文章
相关标签/搜索