977. 有序数组的平方
leetcode链接:有序数组的平方
文档讲解:有序数组的平方
视频链接:代码随想录-有序数组的平方
状态:做出来了
思路:
1、此题主要考虑的是存在负数的情况,不能简单将每个数进行平方;如果存在负数,平方后可能比最右侧数据平方后更大;例如:[-6,1,2,3,4],此时(-6)^2> 4^2 ;
2、考虑用双指针的方式,分别为left(初始为0)和right(num.length-1);然后创建一个新数组,将left2和right2中的最大值放入新数组的最右侧;例如:
3、然后我们遵循左侧优先原则(或者右侧优先),如果left2==right2时,优先将left^2先放入;
代码:
class Solution {
public int[] sortedSquares(int[] nums) {
int[] newArr = new int[nums.length];
int index = nums.length - 1;
int right = nums.length - 1;
int left = 0;
while (left <= right) {
int leftSquares = nums[left] * nums[left];
int rightSquares = nums[right] * nums[right];
if (leftSquares >= rightSquares) {
newArr[index] = leftSquares;
left++;
} else {
newArr[index] = rightSquares;
right--;
}
index--;
}
return newArr;
}
}
209. 长度最小的子数组
leetcode链接:长度最小子数组
文档讲解:长度最小的子数组
视频链接:代码随想录-长度最小的子数组
状态:卡在while (sum>=target) 这里了
思路:
1、此题需要通过滑动窗口(当然其实也需要借助双指针完成)的思想来完成,先定义left和right都为0,然后让right先++,后续累计num[right]走过的值,直到sum[num[right]]>target的值;
2、当sum[num[right]]>target时,记录(right-left+1)记录此时数组长度,通过Math.min()函数记录最小值,记录完之后,在right继续往前走之前,要先将left++,让left也往前走,同时,将sum-num[left],这里需要自己体会;
3、按照1,2,一直走完整个数组,返回最小值min即可;
如下是思路图:
判断sum>=target的循环,要用while而不是用if,这里很关键,第一次做的时候卡死在这了;
代码:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
//保证存在 sum > target 时通过min方法能够取到
int min = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) { //i此时表示right
sum += nums[right];
while (sum>=target) { //此处要用while,不能用if千万注意
min = Math.min(min, (right-left+1));
sum -= nums[left];
left++;
}
}
//如果走完仍然是Integer的最大值,很显然数组中和没有大于target的,按照题意返回0
return min == Integer.MAX_VALUE ? 0 : min;
}
}
59.螺旋矩阵II
leetcode链接:螺旋矩阵II
文档描述:螺旋矩阵II
视频链接:代码随想录-螺旋矩阵II
状态:这题其实之前做过,这次做还是没做好,好多边界情况没有处理好
思路:
1、此题关键在于要明确打印的原则,一层一层的进行打印,先打印最外层,每一层分为上,右,下,左四个部分,分别打印每条边的第一个元素而不打印最后一个元素(这样写的代码就有规律性,如果每个边界有各自的打印方式,代码会非常乱);如下图:
2、思路是,先脑海里抽象出四条线,分别给表示top(最上边一条线),right(最右边一条线),low(最下边一条线),left(最左边一条线);这几天线描绘了当前矩阵最外层的四条边;按照1中的说明分别打印,然后四条线往里缩小;就可以打印完了;画个图举例一下:
代码:
class Solution {
//此题需要打印的是正方形的,n可理解为是正方形的边长
public int[][] generateMatrix(int n) {
//定义需要打印的二维数组
int[][] matrix = new int[n][n];
//起始的打印数字;
int loop = n / 2;
int topLine = 0;
int rightLine = n-1;
int lowLine = n-1;
int leftLine = 0;
int num = 1;
//需要循环打印
for (int loopNumber = 0; loopNumber < loop; loopNumber++) {
//先打印当前层的最上面一边
for (int i = leftLine; i < rightLine; i++) {
matrix[topLine][i] = num;
num++;
}
//先打印当前层的最右边
for (int i = topLine; i < lowLine; i++) {
matrix[i][rightLine] = num;
num++;
}
//先打印当前层的最下边
for (int i = rightLine; i >= leftLine + 1; i--) {
matrix[lowLine][i] = num;
num++;
}
//先打印当前层的最左边
for (int i = lowLine; i >= topLine + 1; i--) {
matrix[i][leftLine] = num;
num++;
}
//往内缩一圈
topLine++;
rightLine--;
lowLine--;
leftLine++;
}
//如果是奇数层,则还需要打印最后一层,其实如果是正方形,只有一个元素了
if (n % 2 == 1) {
for (int i = leftLine; i <= rightLine; i++) {
matrix[topLine][i] = num;
num++;
}
}
return matrix;
}
}