代码随想录算法训练营第二天 | 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II
1 有序数组的平方
注意
有序的数组,平方后按要求排序
题目
解法
1.暴力解法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i = 0; i < nums.size(); i++){
nums[i] = nums[i] * nums[i];
}
sort(nums.begin(),nums.end());//快速排序
return nums;
}
};
2.双指针
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> result(nums.size(), 0);
for(int i = 0, j = k; i <= j ;){ // 需要有两个分号
if(nums[i]*nums[i] >= nums[j]*nums[j]){
result[k--] = nums[i]*nums[i];
i++;
}
else{
result[k--] = nums[j]*nums[j];
j--;
}
}
return result;
}
};
基础知识补充
sort()函数使用。
- sort() 函数位于 头文件中,用于对容器(如数组、向量等)进行排序。它提供了多种重载形式以适应不同的需求
- C++ 的 sort() 函数默认按照升序进行排序。如果需要降序排序,可以在调用 sort() 函数时使用 greater<>() 或者自定义比较函数
#include <algorithm> // 导入头文件
// 用法1:对整个容器进行排序
sort(container.begin(), container.end());
// 用法2:对指定范围内的容器进行排序
sort(container.begin() + start_index, container.begin() + end_index);
// 用法3:使用自定义的比较函数进行排序
sort(container.begin(), container.end(), compare_function);
// 用法4:使用 lambda 表达式进行排序
sort(container.begin(), container.end(), [](const Type& a, const Type& b) {
return a < b;
});
- container 是你要排序的容器,如数组、向量等。
- begin() 和 end() 分别指向容器的起始位置和结束位置。
- start_index 和 end_index 指定了排序范围的起始和结束位置(不包括结束位置)。
- compare_function是一个自定义的比较函数,用于指定排序规则。
2 长度最小的子数组
注意
连续的子数组
题目
解法
- 最初错误解法(理解错误了,需要连续子数组,不只是最少数组)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
// 先排序,然后从最大的开始与target进行比较
sort(nums.begin(),nums.end());
int k = 0;
for(int j = nums.size() - 1; j >= 0; j--){
k += nums[j];
if(k >= target) return (nums.size() - j);
}
return 0;
}
};
2.暴力解法【超时了】
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
// 两个循环,记录可行的子数组长度,并返回最小值
int sum = 0;
int result = INT32_MAX;
int jishu = 0;
for(int i = 0; i < nums.size(); i++){
sum = 0; // 不能在内循环if里,否则出现没有满足的子数组时sum会叠加
for(int j = i ; j < nums.size() ; j++){
sum += nums[j];
if(sum >= target){
jishu = j - i + 1;
result = result > jishu ? jishu : result ;
break;
}
}
}
return result == INT32_MAX ? 0 : result;
}
};
3.滑动窗口(里层的while循环是精髓)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0;
int result = INT32_MAX;
int i = 0;
int subLeng = 0;
for(int j = 0 ; j < nums.size() ; j++){
sum += nums[j];
while(sum >= target){
subLeng = j - i + 1;
result = result > subLeng ? subLeng : result ;
sum -= nums[i++]; //删除前指针指向的值,前指针并向前走一步
//break; // 如果大数组里面有小数组也满足,不会找到小数组,也就是不会找到最小的,比如 [1,4,4] 目标是4,一直会2个元素的数组滑动
}
}
return result == INT32_MAX ? 0 : result;
}
};
基础知识补充
INT32_MAX 是int中最大值。
时间复杂度理解
- 时间复杂度是一个函数,指的是随着输入大小的增长,运行时间会以怎样的速度扩张。
- O(logn),这里log特指log2,是该算法随着输入规模翻倍,操作次数只增加一
3 螺旋矩阵II
注意
寻找不变量
题目
解法
- 左闭右开
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> rec(n, vector<int>(n, 0));
int startX = 0;
int startY = 0;
int loop = n / 2; //圈数,n为奇数时特殊处理
int mid = n / 2; //特殊处理用的
int offset = 1; // 左闭右开中开区间的应用
int count = 1; //填充的元素
int i,j;
while(loop--){
i = startX;
j = startY;
//左上到右上
for(; j < n - offset; j++){
rec[i][j] = count++;
}
//右上到右下
for(; i < n - offset; i++){
rec[i][j] = count++;
}
//右下到左下
for(; j > startY; j--){
rec[i][j] = count++;
}
//左上到左上
for(; i > startX; i--){
rec[i][j] = count++;
}
++startX;
++startY;
offset++;
}
if(n % 2){
rec[mid][mid] = count;
}
return rec;
}
};
4 数组总结
参考:代码随想录总结
数据基础
- 数组是存放在连续内存空间上的相同类型数据的集合
5 感悟
有一些困难,第一遍刷重在理解了