面試題29:順時針打印矩陣
題目要求:
輸入一個矩陣,按照從外向里以順時針的順序一次打印出每一個數字。
如果輸入如下矩陣:
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。
解題思路:
此題的任務清晰明了,需要小心的是要考慮清楚邊界情況。
上例中,環繞一次后,剩下的矩陣行數為2,列數為2,可以看成一個新的矩陣,繼續環繞打印。可見,此題可以用遞歸解決。
示例中行數與列數是相等的,所以能夠組成完整的環(完整指能夠環繞一圈);其實,只要行數和列數中,比較小的那個是偶數,就能夠組成完整的環。
如果行數和列數中比較小的那個是奇數,則遞歸到終止前的剩余元素無法成環。如果較小的是行數,則剩余元素的組成的形狀類似于“|”;如果較小的是列數,則剩余元素的組成的形狀類似于“—”。
因此,當未訪問行數和未訪問列數都大于等于2時,按照完整環的邏輯遞歸訪問即可。當不滿足上述條件,判斷剩余元素是“|”型還是“—”型,然后按照不完整環的邏輯訪問即可。
package chapter4;
/**
* Created by ryder on 2017/7/16.
*
*/
public class P161_PrintMatrix {
public static void printMatrix(int[][] data){
if(data==null)
return ;
if(data.length==0||data[0].length==0)
return ;
int rowMax = data.length-1,rowLen = data.length;
int colMax =data[0].length-1,colLen = data[0].length;
int row=0,col=0,round=0;
while(rowLen-2*row>1 && colLen-2*col>1){
for(;col<=colMax-round;col++){
System.out.print(data[row][col]);
System.out.print("\t");
}
for(col=col-1,row=row+1;row<rowMax-round;row++){
System.out.print(data[row][col]);
System.out.print("\t");
}
for(;col>=round;col--){
System.out.print(data[row][col]);
System.out.print("\t");
}
for(col=col+1,row=row-1;row>round;row--){
System.out.print(data[row][col]);
System.out.print("\t");
}
row=row+1;
col=col+1;
round++;
}
//如果行數與列數中較小的那個是偶數,則能組成完整的環,在while中就完成了遍歷
if(rowLen-2*row==0 || colLen-2*col==0){
System.out.println();
}
//如果行數與列數中較小的是行數,且是奇數,則還需補充訪問一行
if(rowLen-2*row==1){
for(;col<=colMax-round;col++){
System.out.print(data[row][col]);
System.out.print("\t");
}
System.out.println();
}
//如果行數與列數中較小的是列數,且是奇數,則還需補充訪問一列
if(colLen-2*col==1){
for(;row<=rowMax-round;row++){
System.out.print(data[row][col]);
System.out.print("\t");
}
System.out.println();
}
}
public static void main(String[] args){
int[][] data1={
{1,2,3,4},
{12,13,14,5},
{11,16,15,6},
{10,9,8,7},
};
int[][] data2={
{1,2,3,4},
{10,11,12,5},
{9,8,7,6},
};
int[][] data3={
{1,2,3},
{10,11,4},
{9,12,5},
{8,7,6},
};
int[][] data4={
{1,2,3},
{8,9,4},
{7,6,5},
};
printMatrix(data1);
printMatrix(data2);
printMatrix(data3);
printMatrix(data4);
}
}
運行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9