977. 有序数组的平方
暴力解法(简单 时间复杂度o(n*logn))
比较简单,这边就是for循环遍历然后放入新数组,最后排序一下
双指针(o(n))
思路:
数组大的平方和位于数组两端,设置左右指针向中间遍历。
每次将得到较大的平方和放入结果数组中,结果数组指针指向数组末尾。
将有较大平方和的指针向中间靠近(左指针+1or右指针-1)当左指针大于右指针时退出循环。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k =nums.size()-1;//定义新数组指针
vector<int> result(nums.size(),0);//创建一个新数组,大小为nums的size,数值全部为0
int i =0,j=nums.size()-1;//设置两端指针向中间遍历,原数组平方和大数在两端
while(i<=j){//当i<=j时 数组元素还未遍历完成
if(nums[i]*nums[i] < nums[j]*nums[j]){//当i平方和小于j平方和,则左数平方小于右数,右数平方放入结果数组中,右指针-1;
result[k--] = nums[j]*nums[j];
j--;
}else{//当左平方和大于或等于右平方和,则将左数放入结果数组中,左指针+1
result[k--] =nums[i]*nums[i];
i++;
}
}
return result;
}
};
209. 长度最小的子数组
滑动窗口(o(n))
一个for循环
设置初始最终结果res:取最大值(int result = INT32_MAX;)
设置起始位置和终止位置 (int i = 0; // 滑动窗口起始位置,终止位置在for循环当中向右遍历)
设置滑动窗口的总和(int sum =0;)
设置滑动窗口长度( int subLength = 0; // 滑动窗口的长度)
终止位置j 向数组右边滑动 (for循环)
当出现序列数相加大于等于target 则取子序列长度并更新res(while)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int res = INT32_MAX;//结果值设置为一个最大值
int sum =0;//数组当前窗口的累加值
int i=0;//初始位置
for(int j =0;j<nums.size();j++){
sum += nums[j];
//这里使用while 每次更新i(起始位置) 并不断比较子序列是否符合条件
while(sum >= target){
int sublength = (j - i +1);//大于目标值的子序列的长度
res = min(res,sublength);//取最小长度
sum -= nums[i++];//取到大于等于目标值的子序列后初始位置i就要更新位置(向前+1),同时sum要减去nums[i]的值在进行判断当前序列
//是否大于等于target
}
}
return res == INT32_MAX ?0:res;//返回值如果res没有被赋值则不存在子序列返回0,如果被赋值则返回res最小子序列长度
}
};
59. 螺旋矩阵 II
模拟(o(n2))
思路:一条边一条边模拟
设置初始位置sx,sy,
设置一共要循环多少圈(loop = n/2)
设置给矩阵每个位置赋值(count)
当n为奇数时需要对矩阵中心单独赋值 (mid =n/2)
while循环 :当loop不等于0时表示还有圈圈
设置i,j为初始位置sx,sy
上边:从左到右列变换,左闭右开每条边的最后一个位置不遍历(;j<n-offset;j++)循环中赋值res[i] [j] = count ++
右边:从上到下行变换,左闭右开每条边的最后一个位置不遍历(;i<n-offset;i++)
下边:从右到左列变换,左闭右开每条边的最后一个位置不遍历
(;j>sy;j--)
左边:从下到上行变换,左闭右开每条边的最后一个位置不遍历
(;i>sx;i--)
(注意:这里的循环中i,j不断变换 所以不需要赋值)
循环一圈结束开始下一圈时更新初始位置(sx ++,sy++)
控制每行遍历的长度(offset+=1)
特殊:当n为奇数时对中间位置单独处理(if(n%2){ //这里的count赋值后不再++
resmid =count; })
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));//vector容器定义一个二维数组
int sx =0,sy=0;
int loop =n/2;//定义循环几圈,当n为3时循环一圈 ,矩阵中间值单独处理
int count =1;//给矩阵赋值
int mid = n/2;//矩阵中间的位置
int offset = 1;//左闭右开 每条边遍历长度
int i ,j;
while(loop --){
i =sx;
j =sy;
//下面开始模拟转一圈
//上边从左到右(左闭右开)
for(j;j<n - offset;j++){
res[i][j] = count++;
}
//右边从上到下(左闭右开)
for(i;i<n -offset;i++){
res[i][j] =count++;
}
//下边从右到左
for(;j>sy;j--){
res[i][j] =count++;
}
//左边从下到上
for(;i>sx;i--){
res[i][j] =count++;
}
//开始下一圈,起始位置缩小1
sx++;
sy++;
//每一圈遍历的长度也要缩小1
offset+=1;
}
//如果n为奇数 单独给最中间的值赋值
if(n%2){
res[mid][mid] =count;
}
return res;
}
};