lesson1: 有序数组的平方——双指针
leecode链接:LeetCode.977
给你一个按非递减顺序排序的整数数组 nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
示例 1:
- 输入:nums = [-4,-1,0,3,10]
- 输出:[0,1,9,16,100]
- 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]
示例 2:
- 输入:nums = [-7,-3,2,3,11]
- 输出:[4,9,9,49,121]
思路
数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
考虑双指针法,指针i指向起始位置,指针j指向终止位置。定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置,双指针输出的结果对应k指向的result数组输入位置。
如动画所示:
题解
public int[] sortedSquares(int[] nums) {
int k = nums.length-1;
int[] result=new int[nums.length];
int j=k,i=0;
while(i<=j){
if(nums[i]*nums[i]<nums[j]*nums[j]){
result[k]=nums[j]*nums[j];
k--;
j--;
}else{
result[k]=nums[i]*nums[i];
k--;
i++;
}
}
return result;
}
lesson2: 长度最小的子数组
题目来源
leecode链接:209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
思路
滑动窗口:
- 窗口内满足条件的情况:其和 ≥ s 的长度最小的 连续 子数组;
- 窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了,进一步筛选),同时需要注意窗口和的变化。
- 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,终止位置建立for循环
题解
public int minSubArrayLen(int target, int[] nums) {
int sum=0,i=0,result=Integer.MAX_VALUE;
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=target){
result=Math.min(result,j-i+1);
sum-=nums[i];
i++;
}
}
return result==Integer.MAX_VALUE?0:result;
}
相关题目
lesson3:螺旋矩阵II
题目来源
leecode链接:59.螺旋矩阵II
思路
坚持循环不变量原则,遍历四条边的时候,注意那些需要固定,那些需要++。
模拟顺时针画矩阵的过程:
- 填充上行从左到右,startX——>n-offset,++
- 填充右列从上到下,startY——>n-offset,++
- 填充下行从右到左,startX——>0,--
- 填充左列从下到上,startY——>0,--
这里一圈下来,我们要画每四条边,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,每一圈a按照统一的规则画下来。
题解
public int[][] generateMatrix(int n) {
int startX=0,startY=0,i=0,j=0;
int offset=1,count=1;
int[][] result=new int[n][n];
//每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
int loop=n/2;
while(loop>0){
for(j=startY;j<n-offset;j++){
result[startX][j]=count++;
}
for(i=startX;i<n-offset;i++){
result[i][j]=count++;
}
for(;j>startX;j--){
result[i][j]=count++;
}
for(;i>startY;i--){
result[i][j]=count++;
}
startX++;
startY++;
offset++;
loop--;
}
//对奇数特殊处理
if(n%2==1){
result[startX][startY]=count;
}
return result;
}