( 数组) 209. 长度最小的子数组——【Leetcode每日一题】

❓209. 长度最小的子数组

难度:中等

给定一个含有 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

提示:

  • 1 < = t a r g e t < = 1 0 9 1 <= target <= 10^9 1<=target<=109
  • 1 < = n u m s . l e n g t h < = 1 0 5 1 <= nums.length <= 10^5 1<=nums.length<=105
  • 1 < = n u m s [ i ] < = 1 0 5 1 <= nums[i] <= 10^5 1<=nums[i]<=105

进阶:

如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(nlog(n)) 时间复杂度的解法。

思路:滑动窗口

定义两个指针 ij 分别表示子数组(滑动窗口窗口)的开始位置结束位置,维护变量 sum 存储子数组中的元素和(即从 nums[i]nums[j] 的元素和)。

初始状态下, ij 都指向下标 0sum 的值为 0:

  • 每一轮迭代,将 nums[j] 加到 sum,如果 sum ≥ target,则更新子数组的最小长度(此时子数组的长度是 j − i + 1
  • 然后将 nums[i]sum 中减去并将 i 右移,直到 sum < target,在此过程中同样更新子数组的最小长度。
  • 在每一轮迭代的最后,将 j 右移。

( 数组) 209. 长度最小的子数组——【Leetcode每日一题】_第1张图片

代码:(Java、C++)

Java

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
    	int i = 0; // 滑动窗口起始位置
        int sum = 0; // 滑动窗口数值之和
        int ans = Integer.MAX_VALUE;
        for(int j = 0; j < nums.length; j++){
            sum += nums[j];//窗口内所有数的和
            while(sum >= target) {//窗口内所有数的和大于target,则前移i(起始位置)
                ans = ans < j - i + 1 ? ans : j - i + 1;
                sum -= nums[i++];// 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
            }
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }
}

C++

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i = 0; // 滑动窗口起始位置
        int sum = 0; // 滑动窗口数值之和
        int ans = INT_MAX;
        for(int j = 0; j < nums.size(); j++){
            sum += nums[j];//窗口内所有数的和
            while(sum >= target) {//窗口内所有数的和大于target,则前移i(起始位置)
                ans = ans < j - i + 1 ? ans : j - i + 1;
                sum -= nums[i++];// 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
            }
        }
        return ans == INT_MAX ? 0 : ans;
    }
};
运行结果:

( 数组) 209. 长度最小的子数组——【Leetcode每日一题】_第2张图片

复杂度分析:
  • 时间复杂度 O ( n ) O(n) O(n),其中 n 为数组的长度。
  • 空间复杂度 O ( 1 ) O(1) O(1)

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!

你可能感兴趣的:(LeetCode,leetcode,算法,数据结构)