zoukankan      html  css  js  c++  java
  • leetcode每日一题(2020-06-28):209. 长度最小的子数组

    题目描述:
    给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0。

    今日学习:
    1.二分法复习
    2.滑动窗口复习
    3.前缀和复习

    题解:
    1.暴力法:O(n²),O(1)
    2.滑动窗口:O(n),O(1)
    3.前缀和+二分法:O(nlogn),O(n)

    //暴力法居然没超时
    var minSubArrayLen = function(s, nums) {
        if(nums.length == 0) return 0
        let res = Number.MAX_VALUE
        let left = right = 0
        while(left < nums.length) {
            let sum = 0
            let count = 0
            right = left
            for(; right < nums.length; right++) {
                sum += nums[right]
                if(sum >= s) {
                    count = right - left + 1
                    res = Math.min(res, count)
                    break
                }
            }
            left++
        }
        return res == Number.MAX_VALUE ? 0 : res
    };
    //双指针移动滑动窗口,其实我写完暴力法就想到了可以存下中间的sum省去一部分计算,但是开始没想明白怎么做
    var minSubArrayLen = function(s, nums) {
        if(nums.length == 0) return 0
        let res = Number.MAX_VALUE
        let left = right = sum = 0
        while(right < nums.length) {
            sum += nums[right]
            while(sum >= s) {
                res = Math.min(res, right - left + 1)
                sum -= nums[left]
                left++
            }
            right++
        }
        return res == Number.MAX_VALUE ? 0 : res
    }
    //前缀和+二分查找
    var minSubArrayLen = function(s, nums) {
        let n = nums.length
        if(n == 0) return 0
        let res = Number.MAX_VALUE
        let sums = new Array(n + 1).fill(0)
        for(let i = 1; i < n + 1; i++) {
            sums[i] = sums[i - 1] + nums[i - 1]
        }
        for(let i = 1; i < n + 1; i++) {
            let target = s + sums[i - 1]
            let flag = binarySearch(target, i, sums)
            if(flag != -1) {
                res = Math.min(res, flag - i + 1)
            }
        }
        return res == Number.MAX_VALUE ? 0 : res
    }
    var binarySearch = function(target, start, sums) {
        let end = sums.length - 1
        while(start < end) {
            let mid = (start + end) >> 1
            if(sums[mid] < target) {
                start = mid + 1
            }else {
                end = mid
            }
        }
        return sums[start] >= target ? start : -1
    }
    
  • 相关阅读:
    两次动态输入和while的结合使用
    索引切片步长
    12.⽤户登陆(三次输错机会)且每次输错误时显示剩余错误次数(提示:使⽤字符串格式化)
    输出1-100的所以奇数或偶数
    求1-2+3-4+5 ... 99的所有数的和
    求1-100所有数的和
    三次登录机会
    while输入12345689
    while和格式化输出的复合使用
    44
  • 原文地址:https://www.cnblogs.com/autumn-starrysky/p/13201850.html
Copyright © 2011-2022 走看看