977. 有序数组的平方
题目(著作权归领扣网络所有)
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100] 示例 2:
输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]
提示:
1 <= nums.length <= 104 -104 <= nums[i] <= 104 nums 已按 非递减顺序 排序
进阶:
请你设计时间复杂度为 O(n) 的算法解决本问题。
思考
首先观察可知这是一个有序数组,那么平方的最大值一定是在数组两端。据此,再使用双指针,逐个比较,最终得到原数平方的递增数组。
代码
vector<int> sortedSquares(vector<int>& nums) {
vector<int> tmp(nums.begin(), nums.end());
int index1 = 0;
int index2 = tmp.size() - 1;
int i = nums.size() - 1;
//优化 记 n1 = tmp[index1] * tmp[index1] n2 = tmp[index2] * tmp[index2]会简洁一些
while(index1 <= index2){
if(tmp[index1] * tmp[index1] > tmp[index2] * tmp[index2]){
nums[i--] = tmp[index1] * tmp[index1];
index1++;
}
else{
nums[i--] = tmp[index2] * tmp[index2];
index2--;
}
}
return nums;
}
209. 长度最小的子数组
题目(著作权归领扣网络所有)
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。 示例 2:
输入:target = 4, nums = [1,4,4] 输出:1 示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0
提示:
1 <= target <= 109 1 <= nums.length <= 105 1 <= nums[i] <= 105
进阶:
如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。
思考
自己做没什么思路,之前做过一次也想不起来了,所以复习太重要了。暴力解法是挨个从不同的元素开始,比较得出最小符合条件的字串长度。滑动窗口比较巧妙,后面一次是基于前一次的基础上进行的,注意最外层循环变量要作为滑动窗口的右侧,也就是终点,这样实现逻辑比较清晰。
代码
//滑动窗口法
int minSubArrayLen(int target, vector<int>& nums){
int sum = 0;
int result = INT32_MAX;
int i = 0;
for(int j =0; j < nums.size(); j++){
sum += nums[j];
while(sum >= target){
int subLength = j - i + 1;
result = subLength < result ? subLength : result;
sum -= nums[i++];
}
}
return result == INT32_MAX ? 0 : result;
}
//暴力解法
// int minSubArrayLen(int target, vector<int>& nums) {
// int result =INT32_MAX;
// for(int i = 0; i < nums.size(); i++){
// int sum = 0;
// for(int j = i; j < nums.size(); j++){
// sum += nums[j];
// if(sum >= target){
// int subLength = j - i + 1;
// result = result < subLength ? result : subLength;
// break;
// }
// }
// }
// return result == INT32_MAX ? 0 : result;
// }
59. 螺旋矩阵 II
题目(著作权归领扣网络所有)
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]] 示例 2:
输入:n = 1 输出:[[1]]
提示:
1 <= n <= 20
思考
螺旋矩阵这一题对于自己难度也比较大,一开始连思路也不清晰。看了卡哥的讲解视频,了解到了循环不变量这个技巧,就是要保证处理矩阵每一条边的规则要一样,不然代码逻辑就不好写。代码写的过程中出现了一些bug,经过打断点和查看变量,发现问题所在,并以注释的形式记录在了代码中。
代码
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n, 0));
//错误3:vector<vector<int>> matrix; 不初始化,赋值时会报错就会报错
int startx = 0;
int starty = 0;
int offset = 1;
int count = 1;
int loop = n / 2;
while(loop--){//错误4:写成n / 2是错误的,就会死循环
//优化1:for循环还是可以写的更简洁的,如下面随想录的写法
// i = startx;
// j = starty;
// // 下面开始的四个for就是模拟转了一圈
// // 模拟填充上行从左到右(左闭右开)
// for (j = starty; j < n - offset; j++) {
// res[startx][j] = count++;
// }
// // 模拟填充右列从上到下(左闭右开)
// for (i = startx; i < n - offset; i++) {
// res[i][j] = count++;
// }
// // 模拟填充下行从右到左(左闭右开)
// for (; j > starty; j--) {
// res[i][j] = count++;
// }
// // 模拟填充左列从下到上(左闭右开)
// for (; i > startx; i--) {
// res[i][j] = count++;
// }
for(int j = starty; j < n - offset; j++){
matrix[startx][j] = count++;
}
for(int i = startx; i < n - offset; i++){
matrix[i][n - offset] = count++;
}
for(int j = n - offset; j > starty; j--){//错误2: j >= starty是错误的,因为为遵循循不变量原则
matrix[n - offset][j] = count++;
}
for(int i = n - offset; i > startx; i--){
matrix[i][starty] = count++;
}
startx++;
starty++;
offset++;
}
if(n % 2 == 1)
matrix[n / 2][n / 2] = n * n; //错误1 注意数组下标和位序的关系:n / 2 - 1是错误的
return matrix;
}