代码随想录算法训练营第二天 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II
题目(力扣)
题解
977. 有序数组的平方
- 解法:双指针
- 代码
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> square;
int left=0, right=nums.size()-1;
while (right!=left) {
if (abs(nums[left]) <= abs(nums[right])) {
square.push_back(pow(nums[right], 2));
right--;
continue;
}
square.push_back(pow(nums[left], 2));
left++;
}
square.push_back(pow(nums[left], 2));
reverse(square.begin(),square.end());
return square;
}
};
209. 长度最小的子数组
- 心路历程:第一遍做没读懂题,题目需要的是子数组,我以为是其中的元素组成的新数组就可以,结果错。后来想到暴力法的思路,不过没实践,直接看的时间复杂度O(n)的解法。
- 高效解法:滑动窗口法:其实从动画中可以发现滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。(来源:代码随想录)
- 问题:
- 时间复杂度O(n)?
我当时也有这个疑问,不过我想的是这个跟两层for循环显然不一样。计算过程:一层for循环遍历n个元素,循环里面算入总和被访问算一次、窗口划出减掉算一次,共两次,O(2*n)=O(n).
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int sum = 0;
int i = 0;
int sublength = 0;
int result = INT32_MAX;
for (int j=0; j<nums.size(); j++) {
sum += nums[j];
while(sum>=s) {
sublength = j - i + 1;
result = sublength < result ? sublength : result;
sum -= nums[i];
i++;
}
}
return result==INT32_MAX ? 0 : result;
}
};
59. 螺旋矩阵II
- 心路历程:第一遍看题没思路,以前也没看见过,遂看解析。试着理解代码,有了大体了解后(代码也记的差不多)开始敲代码。
- 问题:
- 数组越界:因为一圈螺旋后i和j不在第二圈起始位置,因此需要将
i
和j
重定位到新的startx和starty上; - 二维vector数组定义错误:刚开始看carl代码没注意到这个细节,自己动手时以为返回
vector<vector<int>>
就直接定义就行。结果报错:
Line 1034: Char 9: runtime error: reference binding to null pointer of type 'std::vector<int, std::allocator<int>>' (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:9
对比发现定义不一样,初始化方法如下:
代码 | 说明 |
---|---|
vector v1; | 保存类型为 T 对象。默认构造函数 v1 为空。 |
vector v2(v1); | v2 是 v1 的一个副本。 |
vector v3(n, i); | v3 包含 n 个值为 i 的元素。 |
vector v4(n); | v4 含有值初始化的元素的 n 个副本。 |
且,vector构造函数vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
我的代码:vector<vector<int>> matrix
carl代码:vector<vector<int>> matrix(n, vector<int>(n,0))
可以看到,定义时不填写参数时,调用的默认构造函数使vector为空,此时它并不能当二维数组使用,因此操作会越界;利用C/C++数组存储特点构造数组的数组,并将一维数组元素初始化为存储一维数组的vector即为2维数组。
- 代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n,vector(n,0));
int loop = n / 2;
int startx = 0, starty = 0;
int offset = 1;
int count = 1;
while(loop--) {
int i = startx;
int j = starty;
for (; j<n-offset; j++) {
matrix[i][j] = count++;
} // 这里和卡哥的不一样,直接初始时定位i,j
for (; i<n-offset; i++) {
matrix[i][j] = count++;
}
for (; j>starty; j--) {
matrix[i][j] = count++;
}
for (; i>startx; i--) {
matrix[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if (n % 2) {
int mid = n / 2;
matrix[mid][mid] = count;
}
return matrix;
}
};