Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
Example 1:
Input:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]
Example 2:
Input:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]
本题的思路来自第四题对角线遍历。我们发现,对于二维数组来说,将其视为矩形是一个很不错的思路。本方法中,设置了四个变量分别代表四个将数组视作矩形后的四条边。
countUp ,countDown, countLeft, countRight分别代表上下左右四条边,取int countLeft = 0,countRight=N-1 ,countUp = 0,countDown=M-1,其中M和N分别为行数和列数。程序从第一个元素Matrix[0][0]出发,安规则进行遍历.
(基于第四题的经验,可以很快写出本题的代码,但是比较让人闹心的是逻辑判断条件的设置,如果不细心,将花费大量的时间在逻辑bug调整上)
vector<int> spiralOrder(vector<vector<int>>& matrix) { if (matrix.size() == 0) return{}; vector <int>result = {}; int M = matrix.size(); //获取二维数组行数 int N = matrix[0].size(); //获取二维数组列数 int m = 0, n = 0; //计数器,用来改变下标,从而遍历数组 int countLeft = 0,countRight=N-1 ,countUp = 0,countDown=M-1; //对应矩形的四个边,设置的值对应数组下标。 result.push_back(matrix[m][n]);//第一个元素加入输出数组 while (result.size() != M*N)//直到所有元素都加入到输出数组中循环结束 { if (m == countUp && n == countLeft) {//初始阶段,数组从matrix[0][0]出发,此时在矩形的上边遍历. while (n < countRight) { n++; result.push_back(matrix[m][n]); } countUp++;//上边遍历完成,countUP向下移动 } else if (m == countUp - 1 && n == countRight) { //这里是在矩形右上角的情况,理解m==countUp-1,因为countUp已经下移。 while (m < countDown) { m++; result.push_back(matrix[m][n]); } countRight--;//右边遍历完成,countRight向左移动 } else if (m == countDown && n == countRight + 1)//这里是在右下角的情况,理解 n == countRight + 1 { while (n > countLeft) { n--; result.push_back(matrix[m][n]); } countDown--; } else if (m == countDown + 1 && n == countLeft)//这里是在左下角的情况,理解m == countDown + 1 { while (m > countUp) { m--; result.push_back(matrix[m][n]); } countLeft++; } else if (m == countUp && n == countLeft-1) {//这里是在左上角的情况,理解 n == countLeft-1 while (n < countRight) { n++; result.push_back(matrix[m][n]); } countUp++; } } return result; }