您的位置:首页 > 职场人生

54/59 Spiral Matrix 螺旋矩阵

2017-07-20 12:05 197 查看
54 Spiral Matrix

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example,

Given the following matrix:

[

[ 1, 2, 3 ],

[ 4, 5, 6 ],

[ 7, 8, 9 ]

]

You should return [1,2,3,6,9,8,7,4,5].

这道题让我们将一个矩阵按照螺旋顺序打印出来,我们只能一条边一条边的打印,首先我们要从给定的mxn的矩阵中算出按螺旋顺序有几个环,注意最终间的环可以是一个数字,也可以是一行或者一列。环数的计算公式是 min(m, n) / 2,知道了环数,我们可以对每个环的边按顺序打印,比如对于题目中给的那个例子,个边生成的顺序是(用颜色标记了数字) 红 -> 黄 -> 蓝 -> 绿 -> 黑(这种非对称的遍历方法很重要,对称方法:1,2->3,6->98->74->5, 这种遍历不好处理最后一层环,最后没有AC)。

1 2 3

4 5 6

7 8 9

我们定义p,q为当前环的高度和宽度,当p或者q为1时,表示最后一个环只有一行或者一列,可以跳出循环。此题的难点在于下标的转换,如何正确的转换下标是解此题的关键,我们可以对照着上面的3x3的例子来完成下标的填写,代码如下:

class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> res;
if(matrix.empty() || matrix[0].empty()) return res;               //初始特殊情况判断
int m = matrix.size();
int n = matrix[0].size();
int cir = (min(m, n) + 1) / 2;                                    //环数
int p = m, q = n;
for(int i = 0; i < cir; ++i, p -= 2, q -= 2) {
for(int k = i; k < n-i; ++k) {
res.push_back(matrix[i][k]);                             //注意下标,采用非对称遍历方式
}
for(int k = i+1; k < m-i; ++k) {
res.push_back(matrix[k][n-i-1]);
}

if(p == 1 || q == 1) break;                                  //最后一层环,为避免重复遍历,直接跳出循环

for(int k = n-i-2; k >= i; --k) {
res.push_back(matrix[m-i-1][k]);
}
for(int k = m-i-2; k > i; --k) {
res.push_back(matrix[k][i]);
}
}
return res;                                                      //返回
}
};


59 Spiral Matrix II

Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.

For example,

Given n = 3,

You should return the following matrix:

[

[ 1, 2, 3 ],

[ 8, 9, 4 ],

[ 7, 6, 5 ]

]

思路与前一题相同,代码如下:

class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n));                  //Spiral Matrix 修改版
int cir = (n + 1) / 2;
int m = n;                                                      //令 m = n
int p = m, q = n;
int cnt = 1;
for(int i = 0; i < cir; ++i, p -= 2, q -= 2) {
for(int k = i; k < n-i; ++k) {
matrix[i][k] = cnt++;                                  //矩阵下标不变
}
for(int k = i+1; k < m-i; ++k) {
matrix[k][n-i-1] = cnt++;                              //计数使用cnt++
}

if(p == 1 || q == 1) break;

for(int k = n-i-2; k >= i; --k) {
matrix[m-i-1][k] = cnt++;
}
for(int k = m-i-2; k > i; --k) {
matrix[k][i] = cnt++;
}
}
return matrix;                                                //返回结果
}
};


这两题的关键在于:

1.选择环的个数作为第一层循环变量

2.确定每次循环的下标

3.选择非对称方式遍历

4.及时break
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法面试题