977.有序数组的平方
题目链接:力扣
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
思考过程
- 先平方,再排序
- 视频思路:新开一个容器,利用双指针,两个指针分别指向头和尾,两者平方后比较,哪个大就放入容器尾部,然后向中间靠拢。最后情况是两指针指向同一个元素。
方法一:插入排序
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i,j;
for(i = 0;i < nums.size();i++){
nums[i] = nums[i] * nums[i];
}
//插入排序
int first_unsorted,position,current;
for(first_unsorted = 1;first_unsorted < nums.size();first_unsorted++){
//如果比前一个元素小,后面的元素整体后移,把小元素放到前面去
if(nums[first_unsorted] < nums[first_unsorted - 1]){
position = first_unsorted;
current = nums[first_unsorted]; //暂存
do{
nums[position] = nums[position - 1];
position--;
}while(position > 0 && nums[position - 1] > current);
nums[position] = current;
}
}
return nums;
}
};
方法二:sort函数
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;
}
};
方法三:双指针
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int>result(nums.size(),0); //初始化长度为nums.size()的容器
for(int i = 0, j = nums.size() - 1;i <= j;){ //i==j的时候为双指针同时指向最后一个元素
//哪个大就放入result,i,j两个指针相应向中间靠拢
if(nums[i] * nums[i] < nums[j] * nums[j]){
result[k--] = nums[j] * nums[j];
j--;
}
else{
result[k--] = nums[i] * nums[i];
i++;
}
}
return result;
}
};
209.长度最小的子数组
题目链接: 力扣
思考过程
- 双重for循环遍历
- 视频思路:双指针,j为快指针向右扫,超过target再把i减掉,往后移动
双指针
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0;
int sum = 0;
int subl = 0;
int result = INT32_MAX; //取一个最大值好比较
for(int j = 0;j < nums.size();j++){
sum += nums[j];
while(sum >= target){ //大于等于就不断更新
subl = j - i + 1; //取子序列长度
result = result > subl ? subl : result;
sum -= nums[i++]; //每次都把前面的减掉,等同于双重for循环
}
}
return result == INT32_MAX ? 0 : result;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)
59.螺旋矩阵II
题目链接: 力扣
思考过程
- 混乱
- 视频思路:左闭右开,使用startx,starty两个作为每圈的固定节点,用offset减掉后就变为新的循环
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>>res(n,vector<int>(n,0)); //使用vector定义一个二维数组
int startx = 0,starty = 0; //定义每循环一个圈的起始位置
int loop = n / 2; //每个圈循环几次
int mid = n / 2; //矩阵中间的位置,为了奇数情况设置
int count = 1; //给矩阵中每一个空格赋值
int offset = 1; //控制每一条边遍历的长度,每次循环右边界收缩一位
int i, j;
while(loop--){
i = startx;
j = starty;
//下面四个for循环就是模拟转了一圈,左闭右开
//上行从左到右
for(j = starty; j < n - offset; j++)
res[startx][j] = count++;
//右列从上到下
for(i = startx; i < n - offset; i++)
res[i][j] = count++;
//下行从右到左
for(; j > starty; j--)
res[i][j] = count++;
//左列从下到上
for(; i > startx; i--)
res[i][j] = count++;
//第二圈开始的时候,起始位置各自加上1
startx++;
starty++;
//每一圈里每一条边遍历的长度
offset++;
}
if(n % 2 == 1)
res[mid][mid] = count;
return res;
}
};
- 时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
- 空间复杂度 O(1)
时间复杂度
O(1) < O(logn) < O(n) < O(nlogn) < O() < O() < O() < O() < O()
滑动窗口
滑动窗口适用范围:
在顺序不可变的数组Array中找 连续子数组 array