面试题整理5 顺时针打印矩阵
題目:輸入一個矩陣,按照從外向里以順時針的順序依次打印出每一個數字。
????????? 例如輸入以下矩陣:
?????????? 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)自己寫的代碼,最好想的思路
void PrintMatrixClockwisely2(int** numbers, int columns, int rows) {if(numbers == NULL || columns <= 0 || rows <= 0)return;for( int i=0; i<columns; ++i ){printf( "%d\t",*(*numbers+i) );}for( int i=1; i<rows; ++i){printf( "%d\t",*(*(numbers+i)+columns-1) );}if( rows>=2 && columns>=2 ){for( int i=columns-2; i>=0; --i){printf( "%d\t",*(*(numbers+rows-1)+i) );}for( int i=rows-2; i>=1; --i){printf( "%d\t",**(numbers+i) );}int newRows = rows-2;int newColumns = columns-2;if( newRows == 0 || newColumns==0 ){return;}int ** newNumber = new int*[newRows];for( int i=0; i<newRows; ++i){newNumber[i] = new int[newColumns];}for( int i=0; i<newRows; ++i){for( int j=0; j<newColumns; ++j){*(*(newNumber+i)+j) = *(*(numbers+i+1)+j+1);}}PrintMatrixClockwisely2(newNumber,newColumns,newRows);for( int i=0; i<newRows; ++i){delete[] newNumber[i];}delete[] newNumber;} }(2)附上《劍指offer》中的方法:
分析:打印第一圈的左上角坐標為(0,0),第二圈的坐標為(1,1),依次類推。左上角的坐標中行標和列標總是相同的,于是可以在矩陣中選取左上角為(start,start)的一圈作為我們分析的目標。每次去掉外面的行和列,每次行和列減少2,因此推斷出讓循環繼續的條件是columns>startX*2并且rows>startY*2。同時注意打印一圈時出現僅剩一行或者一列時打印的處理,以及避免重復打印的問題。
這樣避免了(1)中數組的新建和刪除,節省了空間,也避免數組new和delete容易出錯的問題。
同時訪問數組數據時采用下標訪問,而不是指針訪問的方式。
在《C和指針》一書中指出,當數組作為參數時,可以采用數組形式也可以采用指針形式,采用數組形式必須制定列大小,因此在本題中參數采用了指針的形式,同時傳遞行和列的大小(在《劍指offer》一書中大部分數組形式參數還是以指針形式傳遞的)。同時指出,以數組形式訪問數組數據不比以指針訪問形式更高效,但是對于多維數組這樣的形式更加清晰,程序更加易讀,所以最好采用下標形式。
void PrintMatrixClockwisely(int** numbers, int columns, int rows) {if(numbers == NULL || columns <= 0 || rows <= 0)return;int start = 0;while(columns > start * 2 && rows > start * 2){PrintMatrixInCircle(numbers, columns, rows, start);++start;} } void PrintMatrixInCircle(int** numbers, int columns, int rows, int start) {int endX = columns - 1 - start;int endY = rows - 1 - start;// 從左到右打印一行for(int i = start; i <= endX; ++i){int number = numbers[start][i];printNumber(number);}// 從上到下打印一列if(start < endY){for(int i = start + 1; i <= endY; ++i){int number = numbers[i][endX];printNumber(number);}}// 從右到左打印一行if(start < endX && start < endY){for(int i = endX - 1; i >= start; --i){int number = numbers[endY][i];printNumber(number);}}// 從下到上打印一行if(start < endX && start < endY - 1){for(int i = endY - 1; i >= start + 1; --i){int number = numbers[i][start];printNumber(number);}} }void printNumber(int number) {printf("%d\t", number); }
總結
以上是生活随笔為你收集整理的面试题整理5 顺时针打印矩阵的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试题整理 4 合并两个排序的数组
- 下一篇: 面试题整理6 栈的压入、弹出序列