学习耗时:2h
呕心沥血,是我太笨了,大体逻辑确认了以后,调程序调了很久
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix
解答:
(1)解题思路:
a.边界分割
以第二个图为例:
第一趟:1的坐标为(0,0),2的坐标为(0,1),3的坐标为(0,2),因此第一次遍历就遍历除第一行最后一个元素外的元素,并送入nums。
第二趟:4的坐标为(0,3),8的坐标为(1,3),因此第二次遍历就遍历除最后一列最后一个元素外的元素,并依次送入nums。
第三趟:12的坐标为(2,3),11的坐标为(2,2),10的坐标为(2,1),因此第三次遍历就遍历除最后一行第一个元素外的元素,并送入nums。
第四趟:9的坐标为(2,0),5的坐标为(1,0),因此第四次遍历就遍历除第一列第一个元素外的元素,并送入nums。
这样一个循环便完成了。
可以看出如下规律:
第一趟:行数y0不变,列数x依次增加
第二趟:列数x不变,行数x0依次增加
第三趟:行数y不变,列数x依次减少
第四趟:列数x0不变,行数y依次减少。
其中,初始值
int y0=0;int x0=0;
int row=matrix.size(),
int col=matrix[0].size();
int x=matrix[0].size()-1;
int y=matrix.size()-1;
当进行第二次循环时,重复上述思路。
但此时要对x0++,y0++,x–,y–。
b.特殊情况的考虑
- 当输入的矩阵为空时:
直接return nums
。 - 当输入的矩阵为一行或者一列时,按照正常行或列向量输出。
- 当矩阵最外围循环进行完要对里层矩阵循环时,若里层循环只剩一个元素,则要对其单独进行
nums.push_back
。
(2)代码
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> nums;
int row=matrix.size();if(row==0) return nums;
int col=matrix[0].size();if(col==0) return nums;
int c=0;int x=matrix[0].size()-1;int y=matrix.size()-1;int y0=0;int x0=0;
for(int j=0;j<matrix.size()*matrix[0].size();j++)
{
if((c==row*col-(row-2)*(col-2))&&(row*col!=1)&&(row-2>0)&&(col-2>0))
{
c=0;
x0++; y0++;x--;y--;
row=row-2 ? row-2 : 1;col=col-2 ? col-2 :1;
}
for(int i=x0;i<x;i++)
{
nums.push_back(matrix[y0][i]);c++;
if(c==row*col) return nums;
}
for(int i=y0;i<y;i++)
{
nums.push_back(matrix[i][x]);c++;
if(c==row*col) return nums;
}
for(int i=x;i>x0;i--)
{
nums.push_back(matrix[y][i]);c++;
if(c==row*col) return nums;
}
for(int i=y;i>y0;i--)
{
nums.push_back(matrix[i][x0]);c++;
if(c==row*col) return nums;
}
if(row*col==1)
{
nums.push_back(matrix[y0][x0]);c++;
if(c==row*col) return nums;
}
}
return nums;
}
};
结果还可以,,,临表涕零,不知所言。。