977这道题思路清奇,最大的值一定在两边,所以用一个while循环向两边收拢。
但是有一点不太明白。题目说的是非递减序列,难道就是递增?不可以是【5,3,5】?
这个有空再研究。。
209也很有意思.滑动窗口,滑动窗口我们用一个s表示start,e表示end。
那么窗口就是 s和e之间的这一段,在滑动的时候,一会是e挪动,一会是s挪动,窗口长度不固定。
为了求最小值,在for循环中,下标肯定是e
我现在举个例子:
[2,3,1,2,4,3] 长度为7.
那么我们看输入,我们用一个s表示start,e表示end。
第一次。窗口为[2,2],和为2不大于7,说明以e结尾的没有大于7的,e挪s不挪。
第二次。窗口为[2,3],和为5不大于7,那么e继续挪,第三次就是[2,3,1]
到了第4次,[2,3,1,2]和为8说明这个时候说明区间里面的东西比7大了。我们先记下,此时长度为len = 4
这个时候区间内以e=3结尾的会不会还有更小的?我们让s4往右边找找看。[3,1,2]此时小于7了
ok问题来了,这个时候我们肯定e是要右边挪了,那么s怎么处理?
s往左?那么下一次会变成下面的蓝色框的区间 ,可是有必要吗?蓝色框里面的红框之前不是已经算过了吗?
所以干嘛呢?s不动就好了,往右?那以当前s开头的子数组不找了是吧?
所以就是上面这个过程。s挪完e挪,大了就收s,小了就走e。
现在看代码:
class Solution {
// 滑动窗口
public int minSubArrayLen(int s, int[] nums) {
int st = 0; //start,没办法上面输入是s不然我这个开始也叫s了。
int sum = 0;
int res = Integer.MAX_VALUE;
for(int e=0;e<nums.length;e++){ //一个for循环找以e为结束的区间
sum += nums[e]; //先把e收进来
while(sum>=s){ //大了,看看吧st往右边移动,也就是st++,顺便把sum去掉st的值。
res = Math.min(res,e-st+1);
sum -= nums[st++];
}
}
return res == Integer.MAX_VALUE?0:res;
}
}
59 螺旋矩阵2
首先先定义我们要干什么,我们要画圈。只有一个数字n=1我们要画一个圈,n=3的时候9个数字画2个,n等于5有25个画3个圈。由此可得圈数其实就是n/2+1
然后怎么画好点呢?每一条边按着箭头画,肯定都遵循左闭右开的原则,开头画完结尾不画。这样画完一个正方形正好不会重复
确定下起点,drawTime表示圈数,每次起点正好是[drawTime,drawTime],第一圈就是[0,0]第二圈是[1,1].第三圈是[2,2]
我们现在设定x轴与y轴。可以看到最右下角那个其实就是[n-1-drawTime,n-1-drawTime],接下来只需让x和y都在[0,n-1-drawTime]之间反复横跳就可以。
class Solution {
public int[][] generateMatrix(int n) {
int[][] rtn = new int[n][n];
int curr = 1;
//画圈。
for(int drawTime=0;drawTime<=n/2;drawTime++){
//从左到右画,最右边那个不画,此时y固定
int y= drawTime;
int x = drawTime;
for(;x<n-1-drawTime;x++){
rtn[y][x] = curr ++ ;
}
//从上到下画,最下边的不画,此时x轴固定
x = n -1 -drawTime ;
for(y=drawTime;y<n-1-drawTime;y++){
rtn[y][x] = curr ++;
}
//从右边往左边画,y轴固定,x变小
y = n- 1-drawTime;
for(x=n-1-drawTime;x>drawTime;x--){
rtn[y][x] = curr ++;
}
//从下面往上画,x固定,y轴变小
x = drawTime;
for(y=n-1-drawTime;y>drawTime;y--){
rtn[y][x] = curr ++;
}
}
//奇数的话中间还得画一个
if(n%2!=0){
rtn[n/2][n/2] = n * n;
}
return rtn;
}
}