977.有序数组的平方
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文章讲解:代码随想录
第一种解法:暴力
- 直接遍历整个数组,对每个数平方,然后调用库函数,sort(nums.begin(),nums.end())进行快速排序
代码实现
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for (int i = 0; i < nums.size(); i++)
{
nums[i] *= nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
};
第二种解法:双指针法
自己思考
和第27题移除元素一样,很自然的想到了快慢指针,一个指针寻找新数组中所需要的元素,一个指针用来更新数组。每一个数的平方跟下一个数的平方进行比较交换位置。我没有想到这是一个有序的数组,且数组平方最大的元素一定是在两边。和移除元素不一样的是,双指针并不是从左到右的一个移动方式,而是向中间合拢的一个过程。
解题思路
- 思考双指针的走向,是向中间合拢的过程
- 首先要创建一个新数组vector<int> result(nums.size(),0),一个指针指向数组中的元素,因为要求非递减顺序排列,即递增的顺序,最大的数在最右边,两边的元素平方是最大的数,指针由外向内合拢的过程是为了找到最大的数,所以我们按最大的下标到最小的下标依次放入元素。
- 对头部指针指向的元素的平方和尾部指针指向元素的平方进行比较(这里的指针其实是数组的下标),谁大谁就先放入数组中,依次移动,直到两个指针相等,将最后一个元素放入新数组。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size(),0);
int k = nums.size() - 1;
for (int head = 0,tail = nums.size() - 1; head <= tail; )
{
if (nums[head] * nums[head]> nums[tail] * nums[tail])
{
result[k--] = nums[head] * nums[head];
head++;
}
else
{
result[k--] = nums[tail] * nums[tail];
tail--;
}
}
return result;
}
};
遇到的问题
- vector初始化需要指明
- 除了定义一个头指针和一个尾指针,对新创建的数组也要定义一个指针,指向该数组下标最大的位置,不能用尾指针代替,因为两个的变化时刻不同。
- 在写一个数的平方时,写成了(nums[head])^2,C++中没有平方运算符,只能用幂函数和乘积的方法代替。
209.长度最小的子数组
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文章讲解:代码随想录
解题思路
- j指向终止位置,i为初始位置,subLength为滑动窗口的长度。
- 使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件。
- 更新sum和i值。
- INT32_MAX 是指 int 可以去的最大数,如果最后的结果还是这个就说明没有匹配的,就返回 0,有匹配的就返回 result。
代码实现
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int i = 0;
int sum = 0;
int subLength = 0;
for (int j = 0; j < nums.size(); j++)
{
sum += nums[j];
while (sum >= target)
{
subLength = j - i + 1;
result = min(subLength, result);
sum -= nums[i];
i++;
}
}
return result == INT32_MAX ? 0 : result;
}
};
出现的问题
- 一开始不懂INT32_MAX是什么,为什么要写return result == INT32_MAX ? 0 : result;
- sum要减去i起始位置的数,窗口是向右移动的,写成了sum -= nums[j]。
59.螺旋矩阵II
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文章讲解:代码随想录
解题思路
- 首先要有循环不变量的思想,遍历每条边都采用相同的方式且每条边遍历的元素个数都相等。
- 知道二维数组i为行,j为列,定义ystart、xstart分别表示列和行的起始位置,用offset来控制终止位置。
- 如果n为奇数,需要在最后为中间的数赋值。
代码实现
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> num(n, vector<int>(n, 0));
int startx = 0,starty = 0;
int offset = 1;
int count = 1;
int i,j;
int loop = n / 2;
while (loop--)
{
i = startx;
j = starty;
for (j = starty; j < n - offset; j++)
num[startx][j] = count++;
for (i = startx; i < n - offset; i++)
num[i][j] = count++;
for (; j > starty; j--)
num[i][j] = count++;
for (; i > startx; i--)
num[i][j] = count++;
startx++;
starty++;
offset++;
}
if (n % 2)
num[n/2][n/2] = count;
return num;
}
};
出现的问题
- while循环知道要执行n/2次,但将条件这个条件写成了while(n/2),n/2一直为真,所以该循环会永远执行下去。
- 忘记每循环一周需要改变startx、starty和offset。
总结
加上写博客,非常痛苦的四个小时,数组专题终于结束了,一直在安慰自己,第一遍需要看讲解思路是正常的,多刷几遍会越来越好,emmmm。。。坚持啊,每弄懂一道题还挺有成就感!