顺时针打印出矩阵(面试编程或者上机题)

题目:输入一个矩阵,按照从外向里以顺时针顺序依次打印出每一个数字,例如:如果输入如下矩阵:
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。


两年之前,去方正面试的时候,上机让做此道题,想了好久没有想出来,悔恨做了1个小时的笔试卷子.....

今天想把这个经典的面试题搞明白:

思路:

按照题目描述,转圈打印,一圈以从左向右,从上到下,从右向左,从下到上。

如上例子:

1、2、3、4、8、12、16、15、14、13、9、5为第一圈

6、7、11、10为第二圈

这个题目的难点是如何判定多个边界条件。

分析这个循环结束的条件。对一个5×5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2, 2)。我们发现5 > 2 * 2。对一个6×6的矩阵而言,最后一圈有四个数字,对应的坐标仍然为(2, 2)。我们发现6 > 2 * 2依然成立。于是我们可以得出,让循环继续的条件是columns > startX * 2 && rows > startY * 2

递归代码实现:


#include <iostream>

using namespace std;

/*
方法一:递归方式;顺时针循环打印,一圈一圈的打印,先右,再下,再左,再上;打完一圈再打内圈,当不符合条件时,结束。
参数:numbers:二维矩阵;columns:矩阵的列数;rows:矩阵的行数;start:一圈开始的左上角的坐标值(x、y坐标是相同的,例如5X5,第一圈左上角(start,start)即为(0,0)...)
*/
void PrintMatrix(int **number, int columns, int rows, int start=0)
{
    if( !number || columns < 1 || rows < 1 || start < 0 ) 
        return;
    if( columns <= 2*start || rows <= 2*start ) 
        return;

    int stopX = columns - 1 - start;//一圈最右列在坐标中的位置
    int stopY = rows - 1 - start;//一圈最大行在坐标中位置

    //打印此圈中的最上行
    for( int i=start; i<=stopX; i++)
        cout <<number[start][i]<<" ";
    //打印此圈中的最右列
    if(start < stopX) //如果此圈中不止有一列
        for(int i=start+1; i<=stopY; i++)
            cout<<number[i][stopX]<<" ";
    //打印次圈中的最下行
    if(start < stopX && start < stopY)
        for(int i=stopX-1; i >= start; i--)
            cout<<number[stopY][i]<<" ";
	//打印次圈中的最左行
    if(start < stopX && start < stopY - 1)
        for(int i=stopY-1; i >= start+1; i--)
            cout<<number[i][start]<<" ";
    PrintMatrix(number, columns, rows, start+1);//下一圈循环
}
void Test(int columns, int rows)
{
    cout<<"Test Begin:"<<columns<<" columns,"<<rows<<" rows."<<endl;
    if(columns < 1 || rows < 1)
        return;

    int** numbers = new int*[rows];
    for(int i = 0; i < rows; ++i)
    {
        numbers[i] = new int[columns];
        for(int j = 0; j < columns; ++j)
        {
            numbers[i][j] = i * columns + j + 1;
        }

    }
    
    PrintMatrix(numbers, columns, rows);
    cout<<endl;
    for(int i = 0; i < rows; ++i)
        delete[] (int*)numbers[i];
    delete[] numbers;
}
int main()
{
    Test(1,1);
    Test(2,2);
    Test(4,5);
    Test(5,5);
    return 0;
}

非递归的形式,可以参见《剑指offer》http://blog.csdn.net/rsljdkt/article/details/9749915

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值