54/59 Spiral Matrix 螺旋矩阵

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值