刷 June-12-2019
O(n)做就是滑窗,本质还是利用了单调性。左右指针固定只能移动左边,因为移动右边+1肯定不是最优解。2pointer还要再体会下。
public int minSubArrayLen(int s, int[] nums) {
int res = nums.length + 1;
int l = 0;
int temp = 0;
for (int i = 0; i < nums.length; i ++) {
temp += nums[i];
while (l <= i && temp >= s) {
res = Math.min(res, i - l + 1);
temp -= nums[l++];
}
}
return res == nums.length + 1 ? 0 : res;
}
follow up要求 O(NlgN)
lgN一般是二分,N次二分= =但是没仔细想。看了下答案原来是
sum[n]代表1-n的和
遍历1-n,找最大的x => sum[n] - sum[x] >= total,所谓的找使用二分找,顺手写一个复习下二分。
class Solution {
public int minSubArrayLen(int s, int[] nums) {
if (nums.length == 0) return 0;
int res = nums.length + 1;
int[] sum = new int[nums.length];
sum[0] = nums[0];
for (int i = 1; i < nums.length; i ++) {
sum[i] = sum[i - 1] + nums[i];
}
for (int i = 0; i < sum.length; i ++) {
if (sum[i] >= s) {
res = Math.min(res, i - largestIndex(sum, i, s));
}
}
return res == nums.length + 1 ? 0 : res;
}
public int largestIndex(int[] nums, int end, int total) {
int l = 0;
int r = end;
while (l <= r) {
int m = l + (r - l) / 2;
int val = nums[m];
if (nums[end] - val == total) {
r = m - 1;
} else if (nums[end] - val > total) {
l = m + 1;
} else {
r = m - 1;
}
}
return nums[end] - nums[l] >= total ? l : l - 1;
}
}
不是很稳,点了LC的提交来验证。应该锻炼口头代数DEBUG的能力。