顺时针打印矩阵

前言

最近在刷剑指offer,碰到一道题如下:

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 
1 2 3 4 
5 6 7 8 
9 10 11 12 
13 14 15 16 
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

剑指offer里的解法比较难懂,但看了牛客网有人对这题的解法我觉得很棒,特此在这里分享一下。


基本思想

定义四个变量分别对应左上,右上,左下,右下,根据这四个变量顺时针打印一圈,接着四个变量分别向对角缩进一个单位,继续打印,依次循环。如下图所示。

这里写图片描述


代码与测试

#include <iostream>
#include <vector>

using namespace std;

vector<int> printMatrix(vector<vector<int>> matrix)
{
    int row=matrix.size();
    int col=matrix[0].size();

    vector<int> res;

    if(row==0||col==0) return res;

    int left=0,top=0,right=col-1,bottom=row-1;
    while(left<=right&&top<=bottom)
    {
        for(int i=left;i<=right;++i)
            res.push_back(matrix[top][i]);
        for(int i=top+1;i<=bottom;++i)
            res.push_back(matrix[i][right]);
        if(top!=bottom)//防止单行重复回文打印
        for(int i=right-1;i>=left;i--)
            res.push_back(matrix[bottom][i]);
        if(left!=right)//防止单列重复回文打印
        for(int i=bottom-1;i>top;--i)
            res.push_back(matrix[i][left]);
        left++,top++,right--,bottom--;
    }
    return res;
} 
void Test(int colums,int rows)
{
    cout<<"Test Begin: "<<colums<<" columns "<<rows<< " rows.\n";

    if(colums < 1 || rows < 1)
        return;
    vector<vector<int>> matrix(rows,vector<int>(colums));
    for(int j=0;j<rows;j++) {
        for(int k=0;k<colums;k++) {
            matrix[j][k]=j*colums+k+1;
        }
    }
    vector<int> res;
    res=printMatrix(matrix);
    for(auto e:res)
        cout<<e<<"\t";
    cout<<endl;
}
int main()
{
     /*
    1    
    */
    Test(1, 1);

    /*
    1    2
    3    4
    */
    Test(2, 2);

    /*
    1    2    3    4
    5    6    7    8
    9    10   11   12
    13   14   15   16
    */
    Test(4, 4);

    /*
    1    2    3    4    5
    6    7    8    9    10
    11   12   13   14   15
    16   17   18   19   20
    21   22   23   24   25
    */
    Test(5, 5);

    /*
    1
    2
    3
    4
    5
    */
    Test(1, 5);

    /*
    1    2
    3    4
    5    6
    7    8
    9    10
    */
    Test(2, 5);

    /*
    1    2    3
    4    5    6
    7    8    9
    10   11   12
    13   14   15
    */
    Test(3, 5);

    /*
    1    2    3    4
    5    6    7    8
    9    10   11   12
    13   14   15   16
    17   18   19   20
    */
    Test(4, 5);

    /*
    1    2    3    4    5
    */
    Test(5, 1);

    /*
    1    2    3    4    5
    6    7    8    9    10
    */
    Test(5, 2);

    /*
    1    2    3    4    5
    6    7    8    9    10
    11   12   13   14    15
    */
    Test(5, 3);

    /*
    1    2    3    4    5
    6    7    8    9    10
    11   12   13   14   15
    16   17   18   19   20
    */
    Test(5, 4);

    return 0;
}

输出如下:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值