抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

一:题目描述:

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

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

二:示例与提示

示例 1:

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

示例 2:

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

提示:

  • 1 <= target <= 109
  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105

三:思路

暴力求解法

  • 两层循环遍历数组,找到满足条件的所有子数组,再返回长度最小的数组的长度即可
    • 外层循环控制起始位置
    • 内层循环控制终止位置

滑动窗口

  • 不断调整子序列的起始位置和终止位置,从而得到我们想要的结果
  • 用一个for循环就达到了两层循环的效果
  • for循环应表示的是滑动窗口的终止位置
    • 如果表示的是滑动窗口的起始位置,那么还需要一个变量去不断地向右去遍历,这样的逻辑与暴力求解没什么区别,所以不行
    • 利用一个左指针i去表示子序列的起始位置
  • 当窗口的值大于target了,窗口就需要向右移动了,即需要移动左指针使得缩小窗口
  • 当不满足条件之后,即小于target之后,for循环的下次遍历,使得右指针向右移动

209.长度最小的子数组

四:代码 + 复杂度分析

暴力求解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* @param {number} target
* @param {number[]} nums
* @return {number}
*/
var minSubArrayLen = function(target, nums) {
//暴力枚举
//外层循环控制起始位置
//子数组长度存储
//时间复杂度为O(n ^ 2)
let result = Infinity
for(let i = 0; i < nums.length; i++) {
//内层循环控制终止位置
let sum = 0
for(let j = i; j < nums.length; j++) {
sum += nums[j]
if(sum >= target) {
//记录下标
result = Math.min(result, j - i + 1)
break
}
}
}
if(result === Infinity) return 0
return result

};
  • 时间复杂度:O(n ^ 2)
    • 两层for循环嵌套
  • 空间复杂度:O(1)
    • 主要是辅助变量的存储,result,sum都为O(1)

滑动窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
//滑动窗口
//缩小窗口 -- 当遇到含有该字符串的时候
//扩大窗口 -- 外层循环向右移动
if(s.length === 0) return 0
//左指针
let left = 0
let result = -Infinity
const set = new Set()
//一层循环
for(let right = 0; right < s.length; right++) {
let char = s.charAt(right)
while(set.has(char)) {
set.delete(s[left])
left++
}
set.add(char)
result = Math.max(result, right - left + 1)
console.log(result)
console.log(s[right])
}
return result
};

  • 时间复杂度:O(n)
    • n是nums数组的长度,线性时间复杂度算法
  • 空间复杂度:O(1)

评论