LeetCode 977.有序数组的平方
题目链接:
看完题目后就想用两个for循环来做,但是这几天的刷题让我隐隐有一点新的想法,就是用左右两个指针来做。看了一眼代码随想录上的思路过后就直接跳过了暴力解法,转而用双指针法做。
文章链接:
由于这道题涉及到了平方,所以不难想到平方的最大值一定是在数组的两端。那么我们让两个指针分别指向数组两端。再定义一个尺寸和给出的数组一样大的数组,让另定义一个指针指向该数组的尾部,这道题就迎刃而解了。
代码如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int left = 0, right, k, num;
vector<int> nums1(nums.size(), 0);
k = nums.size() - 1;
for (right = nums.size() - 1; left <= right; ) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
nums1[k] = nums[left] * nums[left];
k--; left++;
}
else {
nums1[k] = nums[right] * nums[right];
k--; right--;
}
}
return nums1;
}
};
可能得益于这几天的练习,已经可以较为轻松的解出这种难度的题目了。
LeetCode 209. 长度最小的子序列
题目链接:
在代码随想录的文章中很形象的使用了滑动窗口这个词,不过这道题的本质还是使用快慢指针来做。
文章链接:
这道题用双指针法来做。其中,快指针(fast)用来把数组中的数收入num中,num就表示“窗口”内的子序列之和;慢指针(slow)用来将它指向的值剔除出“窗口”所包含的子序列。在代码随想录的文章中还有一张生动形象的图。那么用代码来实现该想法即为
代码如下
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int slow, fast, sum = 0, size = INT32_MAX, i = 0;
for (slow = 0, fast = 0; fast < nums.size(); fast++) {
sum += nums[fast];
while (sum >= target) {
i = fast - slow + 1;
sum -= nums[slow++];
size = size > i ? i : size;
}
}
return size == INT32_MAX ? 0 : size;
}
};
在纸上捋了一下思路之后再开始写代码发现思路会清晰很多,这个习惯也许可以保留。
LeetCode 59.螺旋矩阵II
题目链接:
这道题我想到了思路,但是在一些细节方面还是没有注意到,这个题不太涉及算法方面的知识,但是却有很多细节需要想清楚。
文章链接:
我想的思路是填入的时候把一行填入完了之后再进行下一行的填入,但是这样就会使代码更为复杂。正确的思路是填入到该行元素的个数减一的位置,至于该行的最后一个元素的填入就交给下一个for循环来做。还有就是和二分法一样的坚持一种区间的思想,因为这道题要注意的边界细节问题比较多,所以坚持一种思想才可以不让自己搞混。
代码如下:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n, 0));
int x = 0, y = 0, middle = n / 2, loop = n / 2, end = 1, num = 1, i, j;//x,y分别代表x轴,y轴的起始位置,middle代表二维数组最中间的位置,loop代表需要循环的次数,end用来控制每次遍历的长度,num用来赋值
while (loop--) {
i = x;
j = y;
for (j = y; j < n - end; j++) {//上面的一行从左到右填入
matrix[x][j] = num++;
}
for (i = x; i < n - end; i++) {//右边的一行从上到下填入
matrix[i][j] = num++;
}
for (; j > y; j--) {//下面的一行从右到左填入
matrix[i][j] = num++;
}
for (; i > x; i--) {//左边的一行从下到上填入
matrix[i][j] = num++;
}
x++; y++;//x,y表示了填入的起始位置,每次填入完成后都需要加一
end += 1;
}
if (n % 2 != 0) {//如果n是奇数的话最中间的值就需要手动填入
matrix[middle][middle] = n * n;
}
return matrix;//最后返回填入完成的二维数组
}
};
从代码可以看出并不是太复杂,但是有很多元素的定义,需要同时兼顾几个元素的变化。这样的代码可以锻炼我们对于自己代码的掌控能力,以后有时间都可以拿出来重新做一做,多扣扣细节。
今日学习4小时收获
今天又一次加深了在数组方面的练习,可以看出数组其实不是想的那么简单,有一些算法还是需要我们熟练掌握的。今天收获了一道以后可以常常拿出来练手感的题,也就是螺旋矩阵这道题,还有就是巩固了昨天练习过的双指针法,能够更熟练的使用这种方法了。最后还是得多多重复,百炼成钢。