刷题008-和大于或等于K的最短子数组
首先,审题要认真,题目说的是>=target的长度最小的连续子数组,也就是返回值最小为0,其次是1
核心思想:设置两个指针left和right,初始都指向0,当sum<target时,right++,sum++,当left<=right且sum>=target时,left++,sum- -;
直到遍历所有的最短子数组
核心代码如下:
class Solution {
public int minSubArrayLen(int target,int[] nums){
int left=0;
int sum=0;
int min=Integer.MAX_VALUE;
for(int right=0;right<nums.length;right++){
sum+=nums[right];
while(left<=right&&sum>=target){
min=Math.min(min,right-left+1);
sum-=nums[left++];
}
}
return min==Integer.MAX_VALUE?0:min;
}
}
例子:
[5,1,4,3] target=7
left | right | 子数组之和 | 与target比较 | 子数组长度 | 下一步操作 |
---|---|---|---|---|---|
5 | 5 | 5 | < | 1 | right向右移动一位 |
5 | 1 | 6 | < | 2 | right向右移动一位 |
5 | 4 | 10 | > | 3 | left向左移动一位 |
1 | 4 | 5 | < | 2 | right向右移动一位 |
1 | 3 | 8 | > | 3 | left向左移动一位 |
4 | 3 | 7 | = | 2 | left向左移动一位 |
3 | 3 | 3 | < | 1 | null |
刷题009-乘积小于k的子数组
和上题的思路差不多:指针right永远不会走到left的左边
所以,当sum>=k时,left++,数组中减少元素,即sum/nums[left++]
每次循环,count=right-left+1(count+right>left),求每段符合空间的子空间,然后进行累加
class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
int sum=1;
int left=0,right=0;
int count=0;
for(right=0;right<nums.length;right++){
sum=sum*nums[right];//右边的指针为乘的过程,也就是加元素
while(left<=right&&sum>=k){
sum/=nums[left++];//左边的指针为除的过程,也就是减元素
}
count+=right>=left?right-left+1:0;//反复叠加的过程,求每段符合区间的子区间数量
}
return count;
}
}