您的位置:首页 > 职场人生

剑指offer 面试题20—顺时针打印矩阵

2015-04-29 19:25 471 查看
题目:

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

例如:如果输入如下矩阵:

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。

基本思想:
通常当我们遇到一个复杂的问题的时候,我们可以用图形帮助我们思考。由于我们是以从外圈到内圈的顺序依次打印,我们在矩阵中标注一圈作为我们分析的目标。在下图中,我们设矩阵的宽度为columns,而其高度为rows。我们我们选取左上角坐标为(startX,
startY),右下角坐标为(endX, endY)的一个圈来分析。



由于endX和endY可以根据startX、startY以及columns、rows来求得,因此此时我们只需要引入startX和startY两个变量。我们可以想象有一个循环,在每一次循环里我们从(startX,
startY)出发按照顺时针打印数字。

接着我们分析这个循环结束的条件。对一个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;  
      
    void PrintMatrixIncircle(int nArr[][4], int rows, int columns, int nStart)  
    {  
        int nEndX = columns - 1 -nStart;  
        int nEndY = rows - 1 -nStart;  

        //从左到右打印一行  
        for (int i=nStart; i<=nEndX; i++)  
        {  
            cout << nArr[nStart][i] << " ";  
        }  
      
        //从上到下打印一列  
        if (nEndY > nStart)  
        {         
            for (int j=nStart+1; j<=nEndY; j++)  
            {  
                cout << nArr[j][nEndX] << " ";  
            }  
        }  
          
        //从右到左打印一行  
        if (nEndY > nStart && nEndX > nStart)  
        {         
            for (int t=nEndX-1; t>=nStart; t--)  
            {  
                cout << nArr[nEndY][t] << " ";  
            }  
        }  
      
        //从下到上打印一列  
        if (nEndY -1 > nStart && nEndX > nStart)  
        {         
            for (int n=nEndY-1; n>=nStart+1; n--)  
            {  
                cout << nArr
[nStart] << " ";  
            }  
        }     
    }  
      
    //顺时针打印矩阵,行数为rows,列数为columns  
    void PrintMatrixClockWisely(int nArr[][4], int rows, int columns)  
    {  
       if (nArr == NULL || rows <= 0 || columns <= 0) 
		   return ;
      
       int nStart = 0;  
       while (rows>(nStart*2) && columns>(nStart*2))     
       {  
           PrintMatrixIncircle(nArr, rows, columns, nStart);  
           nStart++;  
       }  
    }  
      
      
    int main()  
    {  
        int nMatrix[4][4] = {
			{1,2,3,4},
			{5, 6, 7, 8},
			{9, 10, 11, 12},
			{13, 14, 15, 16}};
			
       
        PrintMatrixClockWisely(nMatrix, 4, 4);  
        cout << endl;  
        
        return 0;  
    }


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: