[leetcode] 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].
题意:
给一个m行n列的数组,以螺旋式的方式访问,即绕圈式的访问,以顺时针方向,绕圈往里面依次访问,比如题目中的数组,访问的顺序就是1,2,3,6,9,8,7,4,5.
解题思路:
对于一个m*n的数组,我们每次以一个长方形的方式访问一圈,长方形的起始位置位于长方形的左上角的坐标,比如第一圈的起始坐标是(0,0),第二圈的起始位置将是(1,1)。如下图所示,蓝色的一个长方形代表以(0,0)为起点访问的一圈,红色的矩形代表以(1,1)为起点访问的一圈矩形,黄色的代表以(2,2)为起点访问的一圈。
图一
假设该矩形的起始位置为(i,i),那么该矩形对应的横着的边上需要访问的个数就是row = n-2*i,对应的竖着的边上需要访问的元素个数就是line = m-2*i;访问一个矩形的元素时,可以分为四步去访问,即按照矩形的四条边去访问,如下图所示,分四步去访问矩形的元素。
这里写图片描述
但是需要考虑几种特殊情况:

  1. 第一种情况是矩形缩成了一条边,只剩下一条横着的边或者只剩下一条竖着的边,参见下图:
    这里写图片描述
  2. 矩阵的第2步第4步访问的那两条边不存在,就是说,此时line = 2;参见下图:
    这里写图片描述

以上。
代码如下:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        int m = matrix.size();
        if(m == 0)return vector<int>();
        int n = matrix[0].size();
        vector<int> result;
        int max_start = (((m-1)/2 < (n-1)/2)?((m-1)/2):((n-1)/2));
        for(int start_i = 0; start_i <= max_start; ++start_i){
            int line = m - 2*start_i;
            int row = n - 2*start_i;
            if(row == 1){
                for(int j = 0; j < line; j++){
                    result.push_back(matrix[j + start_i][start_i]);
                }
            }
            else if(line == 1){
                for(int j = 0; j < row; j++){
                    result.push_back(matrix[start_i][j + start_i]);
                }
            }
            else{
                for(int j = start_i; j < row + start_i; ++j)
                    result.push_back(matrix[start_i][j]);
                if(line >= 3){
                    for(int j = start_i + 1; j < line + start_i - 1; ++j)
                        result.push_back(matrix[j][start_i + row - 1]);
                }
                for(int j = start_i + row - 1; j >= start_i; --j)
                    result.push_back(matrix[start_i + line - 1][j]);
                if(line >= 3){
                    for(int j = line - 2 + start_i; j > start_i; --j)
                    result.push_back(matrix[j][start_i]); 
                }
            }
        }
        return result;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值