题目描述:
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
进阶:
如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。
思路:
1. 用双指针 left 和 right 表示一个窗口。sum来表示窗口内数字的和。
2. right 向右移增大窗口,sum随之增加,直到窗口内的数字和sum大于等于了 s。进行第 3 步。
3. 记录此时的长度,left 向右移动,开始减少长度,sum减去移除窗口的数字,每减少一次,就更新最小长度。直到当前窗口内的数字和小于了 s,回到第 2步。
Java双指针解法:
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int len = nums.length;
if (len == 0) {
return 0;
}
int left = 0;
int right = 0;
int sum = 0;
int min = Integer.MAX_VALUE;
while (right < len) {
sum += nums[right];
right++;
while (sum >= s) {
min = Math.min(min, right - left);
sum -= nums[left];
left++;
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}
}
python3解法:
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
length = len(nums)
if length == 0:
return 0
left = 0
right = 0
sums = 0
minlen = sys.maxsize
while right < length:
sums += nums[right]
right += 1
while sums >= s:
minlen = min(minlen, right - left)
sums -= nums[left]
left += 1
if minlen == sys.maxsize :
return 0
else:
return minlen
暴力解法:
思路:
从第 0 个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。
从第 1 个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。
从第 2 个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。
...
从最后个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。
从上边得到的长度中选择最小的即可。
java代码实现
class Solution {
public int minSubArrayLen(int s, int[] nums) {
//暴力解法
int len = nums.length;
if (len == 0) {
return 0;
}
int min = Integer.MAX_VALUE;
for(int i = 0; i < len; i++){
int right = i;
int sum = 0;
while(right < len)
{
sum += nums[right];
right++;
if(sum >= s)
{
min = Math.min(min, right - i);
break;
}
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum