劍指offer 面試題20―順時針打印矩陣
來源:程序員人生 發布時間:2015-05-11 09:21:54 閱讀次數:2545次
題目:
輸入1個矩陣,依照從外向里以順時針的順序順次打印出每個數字。
例如:如果輸入以下矩陣:
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圈作為我們分析的目標。在下圖中,我們設矩陣的寬度為columns,而其高度為rows。我們我們選取左上角坐標為(startX,
startY),右下角坐標為(endX, endY)的1個圈來分析。

由于endX和endY可以根據startX、startY和columns、rows來求得,因此此時我們只需要引入startX和startY兩個變量。我們可以想象有1個循環,在每次循環里我們從(startX,
startY)動身依照順時針打印數字。
接著我們分析這個循環結束的條件。對1個5×5的矩陣而言,最后1圈只有1個數字,對應的坐標為(2, 2)。我們發現5 > 2 * 2。對1個6×6的矩陣而言,最后1圈有4個數字,對應的坐標依然為(2,
2)。我們發現6 > 2 * 2仍然成立。因而我們可以得出,讓循環繼續的條件是columns > startX * 2 && rows > startY * 2。
接下來我們分析如何依照順時針的順序打印1圈的數字。猶如在圖中標注的那樣,我們可以分4步來打印:第1步是從左到右打印1行(上圖中黃色區域),第2步是從上到下打印1列(上圖中綠色區域),第3步從右到左打印1行(上圖中藍色區域),最后1步是從下到上打印1列(上圖中紫色區域)。也就是我們把打印1圈數字這個問題,分解成4個子問題。
值得注意的是,最后1圈可能退化成只有1行、只有1列、乃至只有1個數字,因此打印這樣的1圈就不需要4步了。


#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;
//從左到右打印1行
for (int i=nStart; i<=nEndX; i++)
{
cout << nArr[nStart][i] << " ";
}
//從上到下打印1列
if (nEndY > nStart)
{
for (int j=nStart+1; j<=nEndY; j++)
{
cout << nArr[j][nEndX] << " ";
}
}
//從右到左打印1行
if (nEndY > nStart && nEndX > nStart)
{
for (int t=nEndX⑴; t>=nStart; t--)
{
cout << nArr[nEndY][t] << " ";
}
}
//從下到上打印1列
if (nEndY ⑴ > nStart && nEndX > nStart)
{
for (int n=nEndY⑴; n>=nStart+1; n--)
{
cout << nArr[n][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;
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈