题目描述
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:
[1,2,3,6,9,8,7,4,5]
示例 2:
输入:
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:
[1,2,3,4,8,12,11,10,9,5,6,7]
思路
这题在题意上没有什么特别难理解的地方,并且很容易想到(看标签)这是一道模拟题。唯一需要注意的地方就是边界条件。在遍历完一行或者一列的时候,要修改已经确定的边界值。比如遍历完一行的时候,接下来需要做的操作是遍历列,而此时并不能够从这列的第一个元素开始遍历,因为刚刚遍历行的时候已经遍历过了。
好了话不多说,接下来直接看代码吧。
代码
源码
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int n, m;
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int line_length = matrix.size();//行数
int column_length = matrix[0].size();//列数
vector<int>ans;//答案数组
//四个边界条件,分别代表左,右,上,下四个边界
int left = 0, right = column_length - 1, top = 0, bottom = line_length-1;
//用一个常数num来表示还未遍历的数字,如果num减为0,则代表已经遍历完了
int num = line_length * column_length;
while (num>0) {
//从左边界遍历到右边界
for (int column = left; column <= right; column++) {
ans.push_back(matrix[top][column]);
num--;
}
if (num == 0) break;//如果遍历完成了,立即跳出,避免重复遍历相同元素
top++;//遍历完成以后,上边界需要加一,下一回遍历要从新的上边界开始,同时避免了重复遍历
//从上边界遍历到下边界
for (int line = top; line <= bottom; line++) {
ans.push_back(matrix[line][right]);
num--;
}
if (num == 0) break;
right--;
//从右边界遍历到左边界
for (int column = right; column >= left; column--) {
ans.push_back(matrix[bottom][column]);
num--;
}
if (num == 0) break;
bottom--;
//从下边界遍历到上边界
for (int line = bottom; line >= top; line--) {
ans.push_back(matrix[line][left]);
num--;
}
left++;
//至此,完成了一次顺时针便利
}
return ans;
}
int main() {
cin >> m >> n;
vector<vector<int>> matrix(m,vector<int>(n));
//输入元素值
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
vector<int> ans = spiralOrder(matrix);
//输出元素值
for (int i = 0; i < m * n; i++) {
cout << ans[i] << " ";
}
return 0;
}
运行结果
问题被完美解决。
总结
这是一道比较简单的模拟题,思路很容易想到,代码也不难实现。同时也正是因为这题不难,所以我才选择通过解析它来作为自己的第一篇文章。这是一个开始,以后我也会继续分享自己的学习和工作过程。