一.有序数组的平方
题目
想法
1.暴力
对每个数平方后进行排序
时间复杂度O(n+nlogn)
然而好像连题目中原整数数组为非递减顺序排序这个条件都没有利用
2.双指针
针对原数组为非递减顺序排序条件,很自然想到双指针从数组两边遍历
即对两边指针所指的数进行比较,大的那个数加入新数组,且对应指针移动,返回新数组即可
二.长度最小连续子数组
题目:
想法
1.暴力
两层for循环易得,略
2.滑动窗口(实际上就是双指针)
其实暴力两层for循环时候感觉一般都会有双指针的想法hh
如果用i来找以i下标对应数为最后一元素的数组集合,j来代表前者代表的集合里面以j下标为第一个元素的数组(就是前者第一层循环,后者第二层循环),会发现j其实再i移动的时候不一定要回溯,即可以用两个指针维护一段序列,该序列一步一步试探即可
注意:
第七行要用while而非if,因为如果该滑动窗口加入一个较大的数时,可能要减去多个较小的数才能使得该窗口的数的和小于目标值
三.螺旋矩阵 II
题目:
想法 :
1.按层模拟
一圈一圈的画,然后一圈又分为四条边画,不过需要注意画边的时候每条边需要规定都为左闭右开(为统一)
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int count = 1; // 用来给矩阵中每一个空格赋值
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i,j;
while (loop --) {
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++;
}
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset += 1;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};
2.类似走迷宫(简单一点)
可以用两个数组存储四个向量分别是(1,0),(0,1),(-1,0),(0,-1),开始是用向右走的向量,然后撞墙后切换状态以此类推(这里撞墙是指走到已走过的区域或者走出规定矩形区域)