剑指 Offer 29. 顺时针打印矩阵

原题:剑指 Offer 29. 顺时针打印矩阵
与主站 54 题相同:54. 螺旋矩阵

方法:边界收缩

基本思路

顺时针打印二维数组的过程分为“从左到右、从上往下、从右到左、从下往上”循环过程。每一次遍历完一整行或一整列之后,就可以对边界进行一次收缩约束。

算法流程

  1. 空值处理:当matrix为空时,直接返回空列表即可。
  2. 边界初始化:左边界l初始化为0,右边界r初始化为col,上边界t初始化为0,下边界b初始化为row
  3. 是否打印完毕的标志,边界是否相遇。
打印方向根据边界打印边界向内收缩打印是否完毕
从左向右左边界l,右边界r上边界t加1是否t>b
从上向下上边界t,下边界b右边界r减1是否l>r
从右向左左边界l,右边界r下边界t减1是否t>b
从下向上上边界t,下边界b左边界l加1是否l>r

复杂度分析:

  • 时间复杂度 O(MN)MN 分别为矩阵行数和列数。
  • 空间复杂度 O(1): 四个边界 l , r , t , b 使用常数大小的 额外 空间( res 为必须使用的空间)。
class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res;
        if(matrix.empty()) return res;
        int row=matrix.size(),col=matrix[0].size();
        int l=0,r=col-1,t=0,b=row-1;
        while(true){
            for(int i=l;i<=r;i++){
                res.push_back(matrix[t][i]);
            }
            if(++t>b) break;
            for(int i=t;i<=b;i++){
                res.push_back(matrix[i][r]);
            }
            if(l>--r) break;
            for(int i=r;i>=l;i--){
                res.push_back(matrix[b][i]);
            }
            if(t>--b) break;
            for(int i=b;i>=t;i--){
                res.push_back(matrix[i][l]);
            }
            if(++l>r) break;
        }
        return res;
    }
};

自写代码

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if(matrix.empty()) return result; 
        int row=matrix.size(),col=matrix[0].size();
        addOrderData(matrix,0,row-1,0,col-1);
        return result;
    }

    void addOrderData(vector<vector<int>>& matrix,int rowStart,int rowEnd,int colStart,int colEnd){
        if((rowStart > rowEnd) || (colStart > colEnd)) return;
        int i=rowStart,j=colStart;
        while(i==rowStart && j<=colEnd){
            result.push_back(matrix[i][j]);
            j++;
        }

        i=rowStart+1,j=colEnd;
        if(i > rowEnd) return;
        while(i<=rowEnd && j==colEnd){
            result.push_back(matrix[i][j]);
            i++;
        }
        i=rowEnd,j=colEnd-1;
        if(j < colStart) return;
        while(i==rowEnd && j>=colStart){
            result.push_back(matrix[i][j]);
            j--;
        }
        i=rowEnd-1,j=colStart;
        if(i < rowStart) return;
        while(i>=rowStart+1 && j==colStart){
            result.push_back(matrix[i][j]);
            i--;
        }
        addOrderData(matrix,rowStart+1,rowEnd-1,colStart+1,colEnd-1);
    }
private:
    vector<int> result;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值