有序数组的平方
拿到题目的思考
刚拿到题目的时候,首先想到原数组是非递减顺序,所以平放以后肯定也是两边大中间小。根据昨天做题的思路,首先就想到应该利用双指针从两边向中间挑选需放入的值。简单思考以后的代码如下:
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0,right = nums.length-1;
int size = nums.length;
int [] newNums = new int[size];
while (left<=right){
int l2 = nums[left] * nums[left];
int r2 = nums[right] * nums[right];
if( l2 >r2){
newNums[size-1] = l2;
left++;
}else {
newNums[size-1] = r2;
right--;
}
size--;
}
return newNums;
}
}
教程观后思考
上面的代码在整体逻辑上其实并没有什么大问题,但是很重要的一个点在于我忽略了while的边界问题:left和right是否相等其实只是偶然写成了小于等于。如果两者不相等,在比较到两者相等的时候,会直接跳过,那么最后生成的数组初始必然为0,少更新了一位。
长度最小的子数组
拿到题目的思考
最简单的思路是用两层循环不断对比和的大小,这样做出来leetcode会显示超时。根据上一题的思路应该是使用双指针解题,如何使用双指针让我纠结了很久。去搜索了一些滑动窗口的原理解释仍然有一点迷惑,感觉并不能很好地解决问题
观看教程后的思考
看完了解析以后才恍然大悟,这里一层循环应该循环终止位置。只是看了解析以后有一点点疑惑,挪动开始位置的指针使用了while,最终的复杂度不应该是log(n²)吗?本质上仍然是两层循环,但是内层循环会被暴力解法简单很多(极端情况前面全是1,最后一个是目标值的数组,需要完整的循环两遍),总体来说效率比暴力解法提升了相当多。
最终提交的代码
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum = 0;
int i = 0;
int 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++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
螺旋矩阵II
拿到题目的思考
第一眼看到题目有点震惊,这题也能用代码解?!手动画了一下图,应该是分割成一圈完全相等的四块来解决,圈数应该是外层总圈数的一半。但是这样往下就没有任何其他的思路了。如果边长为奇数,最中间的数应该是边长的平方。
观看教程后的思考
使用一个计数值进行累计统计当前循环了多少圈。每个圈里需要拆成四个部分进行循环,每次循环的累加值都要在下一次循环里再次使用。代码如下:
class Solution {
public int[][] generateMatrix(int n) {
int[][] result = new int[n][n];
int offset = 1;
int count = 1;
while (count < n * n) {
for (int i = offset - 1; i < n - offset; i++) {
result[offset - 1][i] = count++;
}
for (int i = offset - 1; i < n - offset; i++) {
result[i][n - offset] = count++;
}
for (int i = n - offset; i > offset - 1; i--) {
result[n - offset][i] = count++;
}
for (int i = n - offset; i > offset - 1; i--) {
result[i][offset - 1] = count++;
}
offset++;
}
if (n % 2 == 1) {
int i = n / 2;
result[i][i] = count;
}
return result;
}
}
补充
新冠加上工作压力让博客停更了一个月,现在每天都尽量追一点进度,早日补全完整的打卡记录