By Long Luo
Leetcode 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 209. 长度最小的子数组 给定一个含有$n$个正整数的数组和一个正整数$\textit{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 提示: 1 <= target <= 10^9 1 <= nums.length <= 10^5 1 <= nums[i] <= 10^5 进阶: 如果你已经实现 $O(n)$ 时间复杂度的解法, 请尝试设计一个 $O(n\log n)$ 时间复杂度的解法。
方法一:暴力法 思路与算法:
很容易想到,使用 \(2\) 个循环,枚举 \(\textit{nums}\) 中的每个下标作为子数组的开始下标,对于每个子数组 \(i\) ,满足 \(i \le x \le j\) ,使得:
\[ sum=\sum_{x=i}^{j}\textit{nums}[x] \ge $\textit{target} \]
,并更新子数组的最小长度 \(j-i+1\) 。
代码如下所示:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public int minSubArrayLen_bf (int target, int [] nums) { if (nums == null || nums.length == 0 ) { return 0 ; } int len = nums.length; int ans = Integer.MAX_VALUE; for (int i = 0 ; i < len; i++) { int sum = 0 ; for (int j = i; j < len; j++) { sum += nums[j]; if (sum >= target) { ans = Math.min(ans, j - i + 1 ); break ; } } } return ans == Integer.MAX_VALUE ? 0 : ans; }
复杂度分析:
时间复杂度:\(O(N^2)\) ,其中 \(N\) 是数组 \(\textit{nums}\) 的长度。 空间复杂度:\(O(1)\) 。 方法二:双指针 + 滑动窗口 思路与算法:
因为求连续子数组的和 大于某个值,那么很容易想到使用滑动窗口 ,使用双指针 \(left\) 和 \(right\) 表示一个窗口:
\(right\) 向右移增大窗口,直到窗口内的数字和大于等于了 \(target\) ;记录此时的长度,\(left\) 向右移动,开始减少长度,每减少一次,就更新最小长度,直到当前窗口内的数字和 \(< target\) ,回到第 \(1\) 步。 代码如下所示:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public int minSubArrayLen_sw (int target, int [] nums) { if (nums == null || nums.length == 0 ) { return 0 ; } int len = nums.length; int ans = Integer.MAX_VALUE; int sum = 0 ; int left = 0 ; int right = 0 ; while (right < len) { sum += nums[right]; while (sum >= target) { ans = Math.min(ans, right - left + 1 ); sum -= nums[left]; left++; } right++; } return ans == Integer.MAX_VALUE ? 0 : ans; }
复杂度分析:
时间复杂度:\(O(N)\) ,其中 \(N\) 是数组 \(\textit{nums}\) 的长度,指针 \(\textit{start}\) 和 \(\textit{end}\) 最多各移动 \(n\) 次。 空间复杂度:\(O(1)\) 。