LeetCode 977.有序数组的平方
本题主要使用的是双指针法,并且需要开辟一个新的数组。当然最简单的方法就是原地相乘,然后使用vector容器的sort
方法即可。
这里额外复习一下vector容器的一些基础内容:
- 常用的初始化:
vector<int> v1 = v2;
vector<int> v1(v2); //两者等价
vector<int> v1(n,val) //n个值为val的初始化
- 常用的函数:
vector<int> v;
v.push_back(i); //在尾部添加元素
v.insert(pos,val); //在指定位置添加元素,位置为迭代器变量
v.pop_back(); //删除尾部元素
v.erase(pos1,pos2) //删除pos1-pos2的元素,位置为迭代器变量
本题使用双指针法的主要思路就是让指针从两边行进,判断存在负数情况下平方之后与正数平方的大小,然后从末尾插入新数组中。
下面给出代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> res(nums.size(),0);
int k = nums.size() - 1;
for(int left = 0,right = nums.size() - 1; left <= right; ){
if(nums[left] * nums[left] < nums[right] * nums[right]){
res[k--] = nums[right] * nums[right];
right--;
}else{
res[k--] = nums[left] * nums[left];
left++;
}
}
return res;
}
};
需要注意的点是,操作新容器时,直接使用数组类型的访问和赋值方式会让运行速度更快。
LeetCode 209. 长度最小的子数组
本题唯一需要注意的地方是处理满足条件target时对子序列的处理,即:当处理完子序列使其不满足target条件时再进入下一次循环。主要方法也是双指针法(滑动窗口),只要想清楚窗口左右滑动时的条件,基本框架就可以写出来了,需要注意一些细节。
下面给出我自己写的代码:
int minSubArrayLen(int target, vector<int>& nums) {
int ans = nums.size() + 1;
int sum = 0;
for(int left = 0 , right = 0;right <= nums.size() - 1; ){
sum += nums[right];
if(sum < target){
right++;
continue;
}else{
//关键点是需要有这个while逻辑
while(sum >= target){
ans = ans > right - left + 1 ? right - left + 1 : ans;
sum -= nums[left++];
}
right++;
}
}
if(ans == nums.size() + 1) return 0;
return ans;
}
卡哥的代码比较简洁,省略了if逻辑:
for (int j = 0; j < nums.size(); j++) {
sum += nums[j];
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
while (sum >= s) {
subLength = (j - i + 1); // 取子序列的长度
result = result < subLength ? result : subLength;
sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
并且在输出上做了一定的处理:
int result = INT32_MAX;
return result == INT32_MAX ? 0 : result;
LeetCode 59.螺旋矩阵 II
本题还是有一定难度的,了解区间不变原则之后,代码中很多细节还是不太好处理,磕磕绊绊才写出来。本题使用左闭右开我觉得比较好理解,下面直接给出代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> ans(n,vector<int>(n,0));
int x = 0, y = 0;
int count = 1;
int boundary= 1;
int loop = n/2;
while(loop){
int start = boundary - 1;
for(; x < n - boundary; x++){
ans[y][x] = count++;
}
for(; y < n - boundary; y++){
ans[y][x] = count++;
}
for(; x > start; x--){
ans[y][x] = count++;
}
for(; y > start; y--){
ans[y][x] = count++;
}
x++;
y++;
boundary++;
loop--;
}
if(n%2 == 1){
ans[n/2][n/2] = n * n;
}
return ans;
}
};
需要注意的点:
- 需要有一个offset来控制区间的范围
- 需要分奇偶情况,对奇数情况单独处理
- 二维vector的初始化
vector<vector<int>> ans(n,vector<int>(n,0));
数组总结
最后简单说下我认为c++中数组需要注意的地方:
- 数组内存是连续的,二维数组也一样
- 不能删除元素,删除的手法只能是覆盖