Leetcode 977 有序数组的平方
思路:可以用暴力解法,将数组中的数都平方后再排序,时间复杂度是O(nlogn),可以用双指针进行优化,优化后时间复杂度是O(n)
因为数组中有负数存在,且数组是有序的,则平方后数组最大值一定在数组两端中,定义两个指针,一个指向数组第一个元素,一个指向数组最后一个元素,比较两个指针对应的数大小,大的数即为新数组中最大的数,放在最后一个,然后指针移动,继续比较两个指针所指的数,得到第二大的数,放在倒数第二个。以此类推,直到两个指针相遇,要注意循环的终止条件是i<=j
,两指针相遇时所指的数也要放入新数组
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> res(nums.size()); //定义一个新数组用来存储平方后的数
int k=nums.size()-1; //新数组的下标索引
for(int i=0,j=nums.size()-1;i<=j;){ //i和j就是两个下标指针
if(nums[i]*nums[i]>nums[j]*nums[j]){
res[k]=nums[i]*nums[i];
k--;
i++; //i指针向右移动
}
else{
res[k]=nums[j]*nums[j]; //这里包含了i和j对应的数相等的情况
k--;
j--; //j指针向左移动
}
}
return res;
}
};
Leetcode 209 长度最小的子数组
思路:使用滑动窗口算法,先找到符合条件的子数组,然后减小数组长度,看是否满足题意,满足题意就继续减小数组长度,直到不满足题意,用res
记录数组长度的最小值,并判断res
有没有被赋值,没有被赋值就输出0
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int res=INT32_MAX; //初始化为最大值
int len; //序列长度
int sum=0; //用来计算当前窗口的数字和
for(int i=0,j=0;j<nums.size();j++){ //i表示序列起始位置 j表示序列终止位置
sum+=nums[j];
while(sum>=target){
len=j-i+1;
res=min(res,len); //更新序列长度 找到最小序列长度
sum-=nums[i];
i++;
}
}
return res==INT32_MAX?0:res;
}
};
Leetcode 59 螺旋矩阵II
思路:确定好转圈的逻辑,确保每一条边的赋值规则都是相同的,我这里是左闭右开的规则,即循环中包括每一条边的第一个值,不包括每一条边的最后一个值,先得到转圈数为n/2
,然后依次对一圈中的每条边赋值,要注意n为奇数时
,要对中间位置单独赋值
每转一圈转圈的起始位置要改变,转圈的边界位置也要改变
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n)); //定义一个二维数组
int startx,starty; //定义每一圈的起始坐标
startx=starty=0;
int mid=n/2; //n为奇数时中间位置的坐标 n=3时中间位置坐标为(1,1)
int count=1; //数组元素从1开始
int i,j;
int offset=1; //控制每一圈转的长度
for(int k=0;k<n/2;k++){ //k为转圈数 一共转n/2圈
i=startx;
j=starty;
for(;j<n-offset;j++){
res[startx][j]=count++;
}
for(;i<n-offset;i++){
res[i][j]=count++;
}
for(;j>starty;j--){
res[i][j]=count++;
}
for(;i>startx;i--){
res[i][j]=count++;
}
startx++;
starty++;
offset++;
}
if(n%2==1){ //如果n为奇数给中间位置元素单独赋值
res[mid][mid]=count;
}
return res;
}
};