977.有序数组的平方
思路:
1、双指针法,从两头向中间走
2、含有负数,因此两端大,中间小
3、利用for循环进行重复比较,并移动指针
4、创建一个新的数组,把比较后得到的值放新数组里(从大往小,从小往大,都行)
注意:
vector一维数组的初始化方式为vector<int>result(nums.size(), 0);
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
/*
1、双指针法,从两头向中间走
2、含有负数,因此两端大,中间小
3、利用for循环进行重复比较,并移动指针
4、创建一个新的数组,把比较后得到的值放新数组里(新数组从大往小,从后往前放)
*/
int slow = 0;
int fast = nums.size() - 1;
vector<int>result(nums.size(), 0);
for(int i = nums.size() - 1; i >= 0; i--){
if(nums[slow] * nums[slow] > nums[fast] * nums[fast]){
result[i] = nums[slow] * nums[slow];
slow++;
}else if(nums[slow] * nums[slow] <= nums[fast] * nums[fast]){
result[i] = nums[fast] * nums[fast];
fast--;
}
}
return result;
}
};
209.长度最小的子数组
思路:
1、采用滑动窗口,实际上仍是双指针法
2、双指针相比于暴力解法的优点在于:用一个for循环替代两个for循环
3、若窗口内的和 >= target,则记录此时数组的大小,然后开始往外吐,再次判断
4、用一个值来记录数组大小即可,每次都把小的值替换进去,不用全放数组里再判断 (巧用三目运算符)
5、fast是一定每次都得试探的往右移动的,因此for循环的条件里是fast而不是slow。slow只有满足一定条件才移动,在for循环内部实现即可
6、for循环中fast < nums.size()
,而不是fast < size
,后者会由于size = fast - slow + 1
得到一个常数,fast就卡死在那了,不动了。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
/*
1、采用滑动窗口,实际上仍是双指针
2、用一个for循环替代两个for循环
3、若窗口内的和 >= target,则记录此时数组的大小,然后开始往外吐,再次判断
4、用一个值来记录数组大小即可,每次都把小的值替换进去,不用全放数组里再判断
5、fast是一定每次都得试探的往右移动的,因此for循环的条件里是fast而不是slow
6、slow只有满足一定条件才移动,在for循环内部实现即可
7、第5条中,fast的移动是取决于size,而不是nums.size()
8、第7条说的恰恰相反
*/
int slow = 0;
int result = INT_MAX;
int size = nums.size();
int sum = 0;
for(int fast = 0; fast < nums.size(); fast++){
sum = sum + nums[fast];
size = fast - slow + 1;
//cout<< fast <<"轮次" <<" : size = " << size << "sum = " << sum << endl;
while(sum >= target){
//size = fast - slow + 1;
result = result < size ? result : size;
sum = sum - nums[slow];
slow++;
size--;
}
}
return result == INT_MAX ? 0 : result;
}
};
59.螺旋矩阵II
思路:
1、按二分法的区间来转圈,保证逻辑一致就容易分类(1 2 一组, 3 4, 5 6 , 7 8)
2、从数学来讲,1所在位置是(0,0),2在(0,1),以此类推
3、利用for循环,循环赋值
4、但是二维数组咋赋值来着?
5、n分为奇数和偶数。奇数的话中间的点需要单独取(如示例1的数字9),偶数则不需要
6、需要一个可以一直+1的值,用于赋值 (搞个num)
自己写的时候出现的问题:
1、没考虑圈数(loop),光看例题去了,就觉得n = 3就完事了。是错误的
2、我的row 和 column 就是相当于 start_x 和 start_y 专门定义起始位置,每一圈都会变
3、我的index其实和卡哥的offset是一个意思,但我就是只考虑n = 3,所以没有偏移量
4、人家的起始位置是每过一圈过后才改变值的,在for循环里用 i 和 j 初始化成row和column后 用来变化
5、如第2条所说,row 和 column定义转圈的起始位置,因此在第一个for循环里要写result[row][j] = num;
才对。若写成result[i][j] = num;
则会导致n = 4
时赋值位置乱掉,从而出现错误,且其他测试用例也有过不了的,如下图所示:
注意:
vector二维数组的初始化方式为vector<vector<int>> result(n,vector<int>(n, 0));
这样也行vector<vector<int>> result(n,vector<int>(n));
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
/*
1、按二分法的区间来转圈,保证逻辑一致就容易分类(1 2 一组, 3 4, 5 6 , 7 8)
2、从数学来讲,1所在位置是(0,0),2在(0,1),以此类推
3、利用for循环,循环赋值
4、但是二维数组咋赋值来着?
5、n分为奇数和偶数。奇数的话中间的点需要单独取(如示例1的数字9),偶数则不需要
6、需要一个可以一直+1的值,用于赋值 num
没考虑圈数,光看例题去了,就觉得n = 3就完事了。是错误的
我的row 和 column 就是相当于 start_x 和 start_y 专门定义起始位置,每一圈都会变
我的index其实和卡哥的offset是一个意思,但我就是只考虑n = 3,所以没有偏移量
但人家的起始位置是不改变值的,在for循环里用i和j初始化成row和column后用来变化
*/
vector<vector<int>> result(n,vector<int>(n));//查了一下 应该是这样
int row = 0;//行
int column = 0;//列
int num = 1;
int i = 0;
int j = 0;
int mid = n / 2;
int offset = 1;
int loop = n / 2;
while(loop--){//假设n = 4
for(j = column; j < n - offset; j++){
result[row][j] = num;
num++;
}//循环结束后i = 0,j = 3(注意,最后还有个j++,所以j = 3
for(i = row; i < n - offset; i++){
result[i][j] = num;
num++;
}//循环结束后i = 3,j = 3
for(; j > column; j--){
result[i][j] = num;
num++;
}//循环结束后i = 3,j = 0
for(; i > row; i--){
result[i][j] = num;
num++;
}//循环结束后i = 0,j = 0
row++;
column++;
offset++;
}
if(n % 2 == 1){
result[mid][mid] = num;
}
return result;
}
};