转圈打印矩阵
一、题目
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
例子:
1 2
| 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
|
Leetcode:https://leetcode.cn/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/
二、思路
这种题目本身不难,考察的就是基础的编程能力。我们对于矩阵设置两个点,一个点位于左上角,一个点位于右下角。这两个点就可以确定一个小矩阵的大小。
比如,如上题目中的数组 matrix = [[1,2,3],[4,5,6],[7,8,9]]
,当左上角的坐标为:(0,0)
,右下角的坐标为:(2, 2)
。那么所表示的,或者所遍历的就是如下的一个子矩阵。
最外面的一圈遍历结束后,此时可以把左上角的坐标往右下方移动,变成 (1, 1)
。右下角的坐标往左上方移动,变成 (1, 1)
。直到左上角的坐标出现在右下角的坐标的下方或者右边。就说明遍历结束了。但是需要注意的是,如果子矩阵只有一行,或者只有一列的时候,注意不要重复遍历。
三、代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include <vector> #include <iostream>
class Solution { public: std::vector<int> spiralOrder(const std::vector<std::vector<int>>& matrix) { std::vector<int> res; if (matrix.empty()) { return res; } int lu_row = 0, lu_line = 0; int rd_row = matrix.size() - 1, rd_line = matrix[0].size() - 1; for (; lu_row <= rd_row && lu_line <= rd_line;) { for (int i = lu_line; i <= rd_line; ++i) { res.emplace_back(matrix[lu_row][i]); } for (int i = lu_row+1; i <= rd_row; ++i) { res.emplace_back(matrix[i][rd_line]); } if (lu_row == rd_row || lu_line == rd_line) { break; } for (int i = rd_line-1; i >= lu_line; --i) { res.emplace_back(matrix[rd_row][i]); } for (int i = rd_row-1; i > lu_row; --i) { res.emplace_back(matrix[i][lu_line]); } lu_row++, rd_row--; lu_line++, rd_line--; } return res; } };
void print(const std::vector<int>& vec) { for (const auto x : vec) { std::cout << x << " "; } std::cout << std::endl; }
int main() { Solution s; std::vector<std::vector<int>> matrix{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; auto res = s.spiralOrder(matrix); print(res); return 0; }
|