题目
977.有序数组
自己第一想法(20分钟内未做出)
1、先for进行平方,再for进行判断前后大小,前大后小就交换(会有逻辑问题:比如第3个小于第1个这种情况)。
2、先for进行平方,再用sort()函数,在std命名空间内,无法使用。且该方法时间复杂度为。
代码随想录方法
双指针法
-
关键点:非递减顺序数组,平方后一定呈现两头大,中间小。
-
以空间换时间:定义新数组(要指定大小和数组内容),用于存放最终的结果。
-
双指针:分别指向原数组的一头一尾,进行对比,然后取更大的数。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
//定义容器大小为nums.size(),内容用0填补
vector<int> result(nums.size(), 0);
int k = nums.size()-1;
//head指向原数组头,tail指向原数组尾,判断结束条件为它俩重合
for(int head = 0,tail = nums.size()-1;head<=tail;){
//如果head的平方的值大于tail的平方的值
if((nums[head]*nums[head]) > (nums[tail] * nums[tail])){
result[k] = (nums[head]*nums[head]);
k--;
head++;
}
//如果head的平方的值小于等于tail的平方的值
else{
result[k] = (nums[tail]*nums[tail]);
k--;
tail--;
}
}
return result;
}
};
暴力方法:sort()排序
class Solution {
public:
vector<int> sortedSquares(vector<int>& A) {
for (int i = 0; i < A.size(); i++) {
A[i] *= A[i];
}
sort(A.begin(), A.end()); // 快速排序
return A;
}
};
209. 长度最小的子数组
自己想法(15分钟内未做出)
采用双指针方法,快指针进行遍历求和,当sum值大于等于target时,记录快指针下标,则更新现在最小数组长度为快指针的下标+1,且更新慢指针+1,并把慢指针的下标赋值给快指针,再次进行上述运算,直到慢指针指向数组最后则停止。但编译报错,不知道问题出在哪里。
代码随想录方法
运用双指针方法:
-
快慢指针皆指向开头,快指针一直向后滑动,直到找到大于等于target的sum值,判断此时最小数组长度(fast-slow+1),并进行result更新。
-
之后慢指针向后移动1次,相应的sum应当减去开头的值,再次判断sum>=target,满足则慢指针移动,不满足则快指针继续移动,直到快指针指向最后。
-
如果最后的结果result依旧是等于初始定义的
result == INT32_MAX,则表示找不到,返回0。 -
关键点:判断sum>=target要用while循环判断,而不是用if判断。因为当slow向后滑动一次且sum-=num[slow]后,此时得到的sum有可能仍大于等于target,此时相较上一次的result长度就减了1。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int slow = 0;
int fast = 0;
int sum = 0;
int result = INT32_MAX;
//快指针一直向后滑动
while(fast < nums.size()){
//sum累加
sum += nums[fast];
//满足大于等于target的sum值
while(sum>=target){
//此时数组长度
int subL = (fast - slow + 1);
//result更新
result = min(result,subL);
//慢指针向后移动1次,相应的sum应当减去开头的值
sum -= nums[slow];
slow++;
}
fast++;
}
if (result == INT32_MAX) return 0;
return result;
}
};
59.螺旋矩阵 II
代码随想录方法
按照统一左闭右开的规则进行依次填充:
- 1、根据n判断一共会循环几圈:loop = n/2;
- 2、二维容器的定义方法:
vector<vector<int>> res(n,vector<int>(n,0)); - 3、n为奇数时,对中间位置进行单独处理
- 4、每层填充的数的数量有一定规律,利用offset进行控制
- 5、count用于记录要填的数的数值大小
- 6、startx和starty用于记录每圈的起始填充位置,每向内一圈,startx和starty都+1
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
//定义一个二维数组(容器)
vector<vector<int>> res(n,vector<int>(n,0));
//一共转多少圈
int loop = n/2;
//若n为奇数的 中间位置。例如n=3,中间位置为(1,1)
int mid = n/2;
//起始位置
int startx = 0;
int starty = 0;
//圈层控制变量
int offset = 1;
//要填入的数值
int count = 1;
//初始化i和j
int i;
int j;
while(loop--){
i = startx;
j = starty;
//遵循左闭右开进行遍历
//上,j最终加到n-offset-1,并保持
for(j = starty;j<n-offset;j++){
res[i][j] = count++;
}
//右,i最终加到n-offset-1,并保持
for(i = startx;i<n-offset;i++){
res[i][j] = count++;
}
//下,j减到starty+1
for(;j>starty;j--){
res[i][j] = count++;
}
//左,i减到startx+1
for(;i>startx;i--){
res[i][j] = count++;
}
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset++;
}
//上面循环结束若n为奇数,中间的框会没被赋值
if(n%2!=0){
res[mid][mid] = count++;
}
return res;
}
};
今日收获,记录一下自己的学习时长
今日三道题都有一些卡壳,特别最后的数组螺旋,完全无从下手。就算看完一遍视频自己写也出现一些问题。需要加以巩固。
学习时长:3h+30min。