209 长度最小的子数组
滑动窗口+队列
class Solution {
public int minSubArrayLen(int target, int[] nums) {
Queue<Integer> que = new LinkedList<>();
int len = nums.length;
int min_len = Integer.MAX_VALUE;
int sum = 0;
for (int i = 0; i < len; i++) {
que.add(nums[i]);
sum += nums[i];
while (sum >= target) {
min_len = Math.min(min_len, que.size());
if (!que.isEmpty() && sum - que.peek() >= target) {
sum -= que.poll();
} else {
break;
}
}
}
return min_len == Integer.MAX_VALUE ? 0 : min_len;
}
}
时间复杂度
O
(
n
)
O(n)
O(n),所有元素进出队列一次。
空间复杂度
O
(
n
)
O(n)
O(n),
n
n
n是数组的长度,最差情况下队列中包含所有数组元素。
滑动窗口+数组下标
class Solution {
public int minSubArrayLen(int target, int[] nums) {
// Queue<Integer> que = new LinkedList<>();
int len = nums.length;
int min_len = Integer.MAX_VALUE;
int sum = 0;
int start=0;
int end=0;
for (int i = 0; i < len; i++) {
end=i;
sum += nums[i];
while (sum >= target) {
min_len = Math.min(min_len, end-start+1);
if (end>=start && sum - nums[start] >= target) {
sum -= nums[start];
start++;
} else {
break;
}
}
}
return min_len == Integer.MAX_VALUE ? 0 : min_len;
}
}
class Solution {
public int minSubArrayLen(int target, int[] nums) {
// Queue<Integer> que = new LinkedList<>();
int len = nums.length;
int min_len = Integer.MAX_VALUE;
int sum = 0;
int start=0;
int end=0;
while (end<len){
sum+=nums[end];
while (sum>=target){
min_len=Math.min(min_len,end-start+1);
sum-=nums[start];
start++;
}
end++;
}
return min_len == Integer.MAX_VALUE ? 0 : min_len;
}
}
时间复杂度
O
(
n
)
O(n)
O(n)。
空间复杂度
O
(
1
)
O(1)
O(1)。
前缀和+二分查找
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int len=nums.length;
int[] sums=new int[len+1];
sums[0]=0;//sums[i]表示前i个元素的和
int ans=Integer.MAX_VALUE;
for (int i=0;i<len;i++){
sums[i+1]=sums[i]+nums[i];
}
for (int i = 0; i <= len; i++) {
int binarySearch = binarySearch(target + sums[i], sums,i);
if (binarySearch!=-1){
ans=Math.min(ans,binarySearch-i);
}
}
return ans==Integer.MAX_VALUE?0:ans;
}
public int binarySearch(int sum,int[] sums,int l){
//sum=target+sums[i]
int r=sums.length-1;
int mid=(l+r)/2;
int res=-1;
while (r>=l){
mid=(l+r)/2;
if (sums[mid]>sum){
res=mid;
r=mid-1;
}else if (sums[mid]==sum){
res=mid;
break;
}else if (sums[mid]<sum){
l=mid+1;
}
}
return res;
}
}
时间复杂度
O
(
n
log
n
)
O(n\log n)
O(nlogn)。
空间复杂度
O
(
n
)
O(n)
O(n),辅助数组
s
u
m
s
sums
sums。