1.LeetCode977.有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
思路:
问题的关键是,由于原数组是非递减顺序且新数组也要保证非递减顺序,旧数组有可能出现负数的情况,而负数的平方有可能大于正数平方,因此最大的值只能从正负数两端取得,然后依次比较两端的值,逐步确定较大的值。
这种两端比较的方式可以使用双指针方法。
解法
class Solution {
public int[] sortedSquares(int[] nums) {
int left=0;
int right=nums.length-1;
int[] result= new int[nums.length];
int index=nums.length-1;
while(left<=right){
if(nums[left]*nums[left]>=nums[right]*nums[right]){
result[index]=nums[left]*nums[left];
left++;
}else if(nums[left]*nums[left]<nums[right]*nums[right]){
result[index]=nums[right]*nums[right];
right--;
}
index--;
}
return result;
}
}
2.LeetCode209.长度最小的子数组
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
思路:
解题关键是:①使用滑窗;②确定满足条件的滑窗后,以结束位置作为主轴,动态的右移起始位置缩小滑窗来满足条件。最终获取以结束位置确定的滑窗内的所有满足条件的子数组。
子数组有两个判断条件:①总和大于等于target;②长度最小
解答
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i=0;
int j=0;
int sum=0;
int length=0;
int result=Integer.MAX_VALUE;
for(j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=target){
length=j-i+1;
result=length<result?length:result;
sum-=nums[i++];
}
}
return result!=Integer.MAX_VALUE?result:0;
}
}
3.LeetCode59.螺旋矩阵II
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
思路:
问题的关键是要记住几个重要的参数含义和每个边分析的范围:
①n/2:表示会嵌套几圈
②
startx++; 确定下一圈的起始位置x
starty++; 确定下一圈的起始位置y
③每个边都会空最后的位置作为下一个边的起始位置,单边只分析边长-1的长度。
④每一圈的由左到右和由上到下的结束边界位置是n-1-offset,其中offset是右边界左移或下边界上移位置数,从1开始。
解法
class Solution {
public int[][] generateMatrix(int n) {
int[][] result=new int[n][n];
int loop=n/2;//共循环几圈
int startx=0;//每一圈的起始位置x
int starty=0;//每一圈的起始位置y
int offset=1;//每一圈的右边界左移位置数。
int count=1;//每个空格需要填入的值
int i=0;
int j=0;
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>starty;j--){
result[i][j]=count++;
}
//由下向上移动
for(;i>startx;i--){
result[i][j]=count++;
}
startx++;//确定下一圈的起始位置x
starty++;//确定下一圈的起始位置y
offset++;//右边界左移
loop--;//圈数减一
}
//n为奇数时
if(n%2!=0){
result[startx][starty] = count;
}
return result;
}
}
代码分析:
①n为奇数时,要把最终的值手动放到中间位置。
②一次循环结束后,i又回到了上一个循环的起始位置,因此在新的循环中,要从新的起始位置startx开始分析,不能从i开始。