59、螺旋矩阵2
该题最关键的在于,按照一个什么样的流程去逐渐填充这个二维矩阵。具体是可以按照数字的顺序来进行填充,那么关键就在于每一次循环的时候当前这个正方形的四条边,要四次循环,并且每一次循环边界条件都要一致。
例如代码随想录中的图,就是这四次循环每一次都是从最左边开始,不包含最右边。只要坚持住原则就可以了
具体的代码为:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n,vector<int>(n,0));//初始化一个二维矩阵来存放数据
int loop = n / 2;//这是循环的次数
int mid = n / 2;// 对于奇数来说,循环之后正中间还需要进行填充
int startx = 0;
int starty = 0;
int i,j;
int count = 1;//作为填充的数字
int curNum = 1;//记录当前循环的次数
while(loop--){
i = startx;
j = starty;
//第一层循环,画上方的从左到右
for(j = starty; j < n - curNum;j++){
result[i][j] = count++;
}
//第二层循环,画右边的上到下
for(i = startx; i < n-curNum;i++){
result[i][j] = count++;
}
//第三层循环,画最下边的右到左
for(; j > starty;j--){
result[i][j] = count++;
}
//第四层循环,画左边的下到上
for(; i > startx;i--){
result[i][j] = count++;
}
startx++;
starty++;
curNum++;
}
if(n %2 == 1){//n为奇数,还需要填充一下正中心
result[mid][mid] = count;
}
return result;
}
};
54、螺旋矩阵
该题和上一题很类似,但复杂在于其可能不是方阵,因此单单靠上面四个循环是无法解决问题的,还要考虑其他的可能性。这里我本来也是想要按照上面四层循环的方式后再来判断特殊情况,但觉得思路不够清晰,因此参考了大佬的代码:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int>result;
if(matrix.empty()){ //如果数组为空
return result;
}
int upIndex = 0; // 上边界
int downIndex = matrix.size() - 1;// 下边界
int leftIndex = 0;// 左边界
int rightIndex = matrix[0].size() - 1; // 右边界
while(true){
for(int i = leftIndex ; i <= rightIndex; i++){
result.push_back(matrix[upIndex][i]);
}
if(++upIndex > downIndex){
break;//如果上边界大于下边界就循环结束
}
for(int i = upIndex; i <= downIndex;i++){
result.push_back(matrix[i][rightIndex]);
}
if(--rightIndex < leftIndex){
break;
}
for(int i = rightIndex; i >= leftIndex;i--){
result.push_back(matrix[downIndex][i]);
}
if(--downIndex < upIndex){
break;
}
for(int i = downIndex;i >= upIndex;i--){
result.push_back(matrix[i][leftIndex]);
}
if(++leftIndex > rightIndex){
break;
}
}
return result;
}
};
其核心思想就是每走过一次循环,就把那层循环所走过的路径给“删除掉”,然后直接上下或者左右边界重叠,即可退出循环。