977.有序数组的平方
方法1:双指针比较左右最大数
思路:
1.定义左指针l=0,右指针r=nums.size()
2.开始比较左右指针的平方大小,若是右边的指针是更大的一方,则从后开始,放入新创建的数组arr中,然后r--;若左边的指针是更大的一方,则继续放入arr,并循环直到l<r,即原数组的所有元素都被取到。最后返回arr
3.由于只在循环插入arr的时候进行数组元素平方大小的遍历,因此时间复杂度是O(n)
代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int l = 0,r = nums.size();
vector<int> arr(nums.size());
while(l < r){
for(int i = nums.size()-1;i >= 0 ;i--){
if(nums[l] * nums[l] <= nums[r-1] * nums[r-1]){
arr[i] = nums[r-1] * nums[r-1];
r--;
}
else{
arr[i] = nums[l] * nums[l];
l++;
}
}
}
return arr;
}
};
方法2 暴力做法
思路:直接所有数平方,然后sort函数排序,时间复杂度O(n+nlogn)
代码:
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; }
};
209 长度最小的子数组
思路:由于限制1是要求找出最小区间;限制2是区间内的和大于等于target,因此考虑用滑动窗口动态寻找目标区间的长度大小
1.定义l=0为窗口的左端点,定义累计和sum用来和target比较,从数组的第一个元素i=0开始累加,直到sum >= target,此时窗口的长度为i-l+1,需要判断是否为最小长度,因此定义length用来存储每次sum判断的区间长度
2.只有遍历完整个区间才能找到满足条件的最小区间,因此窗口的左端点l++,然后sum-nums[l]。此时窗口内部的sum一定不满足条件,因此sum[i++],继续添加数组元素到区间内。此时窗口为动态向右滑动的过程,当i到达右边界,而区间内的sum仍然大于target,就需要继续移动窗口左端点,此时区间长度逐渐减小,最后跳出sum>=target的条件后获得的length即为最小区间长度
3.最后判断是否length和初始定义的区间长度一致,如果一致,说明整个的区间和都不满足大于等于target,因此返回0
代码:
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
int l = 0,sum = 0; int length = n + 1;
for(int i = 0;i < n;i++) {
sum += nums[i];
while(sum >= target) {
length = min(length,i - l + 1);//l是窗口的左端点,i是窗口的右端点
sum -= nums[l++];//窗口向右滑动一格 } }
return length != n + 1 ? length : 0;
} };
思路:
碰到类似需要进行多个判断的矩阵,可以考虑使用偏移量来减少判断次数,试用题目像:马走日,国际象棋的骑士每次只能走八个格子等。
本题的数字填充有四个方向,因此假设中间值为(x,y),则可以获得其余四个方向紧挨的数字的偏移量,将上下左右四个方向用数字0,1,2,3表示,并对4取模,使得每次到达边界的时候可以有效的更换方向,然后将x的偏移量表示为{-1,0,1,0},y的偏移量表示为{0,1,0,-1},最后横纵坐标等于之前的加上偏移量。
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n, 0));
int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};//设置x和y轴的偏移量
int x = 0,y = 0,d = 1;//d=1此时先往右填充
for(int i = 1;i <= n * n;i++){
matrix[x][y] = i;
int a = x + dx[d],b = y + dy[d];//此时的横纵坐标由原来的坐标加对应轴的偏移量获得
if(a < 0 || a >= n || b < 0 || b >= n || matrix[a][b] != 0){//如果横纵坐标都越界,或即将填充的格子有元素
d = (d + 1) % 4;//更换方向
a = x + dx[d],b = y + dy[d];
}
x = a,y = b;
}
return matrix;
}
};