代码随想录算法训练营第二天| 977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II
LeetCode977. 有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/description/
视频讲解:
自己实现
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> res;
int z;
for(z = 0; z < nums.size(); z++) {
if(nums[z] >=0) break;
}
int l = z - 1, r = z;
while(l >= 0 && r < nums.size()){
int a = nums[l] * nums[l];
int b = nums[r] * nums[r];
if(a < b){
res.push_back(a);
l--;
}else {
res.push_back(b);
r++;
}
}
while(l >= 0) {
res.push_back(nums[l] * nums[l]);
l--;
}
while(r < nums.size()) {
res.push_back(nums[r] * nums[r]);
r++;
}
return res;
}
};
看了carl的题解感觉自己的有点傻,虽然时间复杂度也是 O(n) 的
题解
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> res(nums.size(), 0); // 这里跟上面的k要区分开来,上面的k指向数组最后一个数,这里是初始化数组大小
int l = 0, r = nums.size() - 1;
while(l <= r){
int a = nums[l] * nums[l];
int b = nums[r] * nums[r];
if(a > b){ // 跟自己写的方法相反,最大的先写进数组,所以选大的
res[k--] = a;
l++;
}else {
res[k--] = b;
r--;
}
}
return res;
}
};
总结
- 总是按照常规想问题,这个问题其实从后往前写会写的更顺,我那样正着去实现考虑的东西更多,麻烦了
LeetCode209. 长度最小的子数组
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/description/
视频讲解:
自己实现
暴力
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int mlen = INT_MAX;
for(int i = 0; i < nums.size(); i++) {
int sum = 0, len = 0;
for(int j = i; j < nums.size() && sum < target; j++) {
sum += nums[j];
len++;
}
if(sum >= target)
mlen = min(mlen, len);
}
return mlen == INT_MAX ? 0 : mlen;
}
};
看思路以后
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0;
int mlen = INT_MAX;
int l = 0, r = -1;
int size = nums.size();
while(l < size && r < size) {
if(sum < target) { // 小了就移动右边窗口,扩大
r++;
if(r < size) sum += nums[r];
}else { // 大了就移动左边窗口,减小
int len = r - l + 1;
mlen = min(len, mlen);
sum -= nums[l];
l++;
}
}
return mlen == INT_MAX ? 0 : mlen;
}
};
题解
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0;
int mlen = INT_MAX;
int l = 0, r = -1;
int len = 0;
for(int r = 0; r < nums.size(); r++) { // 控制右边窗口
sum += nums[r];
while(sum >= target) {
len = r - l + 1;
mlen = min(mlen, len);
sum -= nums[l];
l++;
}
}
return mlen == INT_MAX ? 0 : mlen;
}
};
总结
- 暴力解法是用两层
for
循环,外层控制开始位置,内层控制结束位置 - 如何使用一个
for
循环实现,如果还是控制开始位置跟暴力法还是一样,因此为了跳出这个方法,用循环控制结束位置 - 用
sum
和target
的关系来控制滑动窗口的移动
LeetCode59. 螺旋矩阵 II
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/description/
视频讲解:
自己实现
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>>res(n, vector<int>(n, 0));
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int x = 0, y = 0;
int c = 0;
for(int i = 1; i <= n * n; i++) {
res[x][y] = i;
int a = x + dx[c];
int b = y + dy[c];
if(a >= n || a < 0 || b >= n || b < 0 || res[a][b]) {
c = (c + 1) % 4;
a = x + dx[c];
b = y + dy[c];
}
x = a, y = b;
}
return res;
}
};