Problem: 209. 长度最小的子数组
思路
方法一: 暴力法(爆内存)
方法二: 二分法
方法三: 滑动窗口方法
复杂度
方法一: O(n^2)
方法二: O(nlogn)
方法三: O(n)
Code_1
//方法一:暴力法(过不了)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
// 找出该数组中满足其总和大于等于 target 的长度最小的 连续 子数组
// target = 7, nums = [3,1,3,2,4,3] 输出2 子数组 [4,3] 是该条件下的长度最小的子数组。
if (nums.length==0) {
return 0;
}
int minlength=Integer.MAX_VALUE;
int temp=Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
int sum=0;
for (int j = i ; j < nums.length; j++) {
sum = sum + nums[j];
if (sum >= target) {
temp=j-i+1;
if (temp < minlength) {
minlength = temp;
}
break;
}
}
}
//不存在满足条件的子数组 返回0
return minlength==Integer.MAX_VALUE?0:minlength;
}
}
code_2
//方法二:二分法
class Solution {
public int minSubArrayLen(int num, int[] nums) {
int length = nums.length;
if (length == 0) {
return 0;
}
int ans = Integer.MAX_VALUE;
int[] pres = new int[length + 1];
// 为了方便计算,令 size = n + 1
// pres[0] = 0 意味着前 0 个元素的前缀和为 0
// pres[1] = A[0] 前 1 个元素的前缀和为 A[0]
// 以此类推
for (int i = 1; i <= length; i++) {
pres[i] = pres[i - 1] + nums[i - 1];
}
for (int i = 1; i <= length; i++) {
int target = num + pres[i - 1];
int bound = Arrays.binarySearch(pres, target);
if (bound < 0) {
bound = -bound - 1;
}
if (bound <= length) {
ans = Math.min(ans, bound - (i - 1));
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
Code_3
//方法三:滑动窗口
class Solution {
// 滑动窗口
public int minSubArrayLen(int s, int[] nums) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum = sum + nums[right];
while (sum >= s) {
result = Math.min(result, right - left + 1);
sum = sum - nums[left];
left++;
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}