day02 打卡977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
day02 打卡977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
977.有序数组的平方
1.暴力解法。各个数平方后,调用Arrays的sort()直接排序。sort()的时间复杂度是O(n*log(n))
class Solution {
public int[] sortedSquares(int[] nums) {
for (int i = 0 ; i< nums.length ; i++) {
nums[i] = nums[i] * nums[i];
}
Arrays.sort(nums);
return nums;
}
}
2.双指针法。两端的数肯定是最大之一,左指针指向0,右指针指向n-1。比较两者平方大小,大的就放到新数组的尾巴。最大的一方指针向前或向后移动,循环比较大小。
class Solution {
public int[] sortedSquares(int[] nums) {
int n = nums.length;
int[] result = new int[n];
int left = 0;
int right = n-1;
int index = n-1;
while(left <= right) {
if (nums[left] * nums[left] < nums[right] * nums[right]) {
result[index] = nums[right] * nums[right];
right--;
} else {
result[index] = nums[left] * nums[left];
left++;
}
index--;
}
return result;
}
}
209.长度最小的子数组
1.暴力解法。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int min = Integer.MAX_VALUE;
int sum = 0;
int length = 0;
for (int i = 0 ; i<nums.length ; i++) {
sum = 0;
for (int j = i; j<nums.length ; j++) {
sum += nums[j];
if (sum >= target) {
length = j-i+1;
min = length < min ? length : min;
break;
}
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}
}
2.滑动窗口。想不出来解法,先看了视频,然后在自己写了一遍。
这是我看完写的版本,虽然运行成功,但是理解出现了偏差。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int min = Integer.MAX_VALUE;
int sum = 0;
int length = 0;
for (int j = 0 ; j<nums.length ; j++) {
sum += nums[j];
int i = 0;
int innerSum = sum;
while (innerSum >= target) {
length = j-i+1;
min = length < min ? length : min;
innerSum -= nums[i];
i++;
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}
}
注意:因为是连续最小和。所以每次i不需要重新从下标0开始,直接是从上一次的最左边开始。int i = 0要放到循环的外面。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int min = Integer.MAX_VALUE;
int sum = 0;
int length = 0;
int i = 0;
for (int j = 0 ; j<nums.length ; j++) {
sum += nums[j];
while (sum >= target) {
length = j-i+1;
min = length < min ? length : min;
sum -= nums[i];
i++;
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}
}
59.螺旋矩阵II
画图后,发现是有规律的。可以一圈一圈地顺时针顺序赋值。需要注意n偶数还是奇数需要不同处理的地方。n=4和n=5时,循环次数是2,但是奇数的中间还需要一个值,即25。
一开始没有借助开始坐标的xy值和offset,导致很多for循环里面的意思很复杂。
class Solution {
public int[][] generateMatrix(int n) {
int[][] result = new int[n][n];
if (n%2 != 0) {
// 奇数
result[n/2][n/2] = n*n;
}
// 需要循环的圈层
int loop = n/2;
// 需要遍历的长度,n-1,n-2,n-3...
int offset = 1;
// 开始的数字
int start = 1;
// 开始的横坐标
int startX = 0;
// 开始的纵坐标
int startY = 0;
int i = 0, j = 0;
while (loop >= 1) {
for (j = startY ; j<n-offset ; j++) {
result[startX][j] = start++;
}
for (i = startX ; i<n-offset ; i++) {
result[i][j] = start++;
}
for ( ; j>startY ; j--) {
result[i][j] = start++;
}
for ( ; i>startX ; i--) {
result[i][startY] = start++;
}
loop--;
offset++;
startX++;
startY++;
}
return result;
}
}
数组篇总结
需要掌握二分查找,看到有序数组,就可以想想能不能使用二分查找解决。并且注意界限,我一般使用left<=right的界限,即左闭右闭。
需要掌握双指针法,如快慢指针和两端指针,每次写题目都联想不到使用双指针,需要看了代码随想录的提醒之后才能想得到使用方法。
二维数组的螺旋矩阵需要明晰的界定。每次循环的数与数之间不能重合。

浙公网安备 33010602011771号