【Java】 劍指offer(29) 順時針打印矩陣

本文參考自《劍指offer》一書,代碼採用Java語言。html

更多:《劍指Offer》Java實現合集  java

題目 

  輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每個數字。post

思路

  每次打印矩陣最外面的一圈(用方法printMatrixInCircle()表示),每次都是這個操做,因此能夠採用遞歸。每次打印矩陣的左上角的橫縱座標相同,即爲start,而其他三個角的座標都與行列數以及start有關,所以只須要for循環便可實現打印。測試

  固然,其實只要針對start進行循環判斷,start*2的值小於行數和列數時才須要繼續打印,這樣,經過這個條件,能夠用循環來打印每次的最外圈矩陣。url

測試算例 spa

  多行多列,單行多列,多行單列,一個數的矩陣,空矩陣,nullcode

Java代碼

//題目:輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每個數字。

public class PrintMatrix {
	public void printMatrix(int[][] matrix) {
		if(matrix==null || matrix.length<=0)
			return;
		printMatrixInCircle(matrix, 0);
	}	
	
	private void printMatrixInCircle(int[][] matrix,int start) {
		int row=matrix.length;
		int col=matrix[0].length;
		int endX=col-1-start;
		int endY=row-1-start;
		if(endX<start || endY<start)
			return;
		//僅一行
		if(endY==start) {
			for(int i=start;i<=endX;i++) {
				System.out.print(matrix[start][i]+" ");
			}
			return;  //記得結束
		}
		//僅一列
		if(endX==start) {
			for(int i=start;i<=endY;i++) {
				System.out.print(matrix[i][start]+" ");
			}
			return;  //記得結束
		}				
		
		//打印邊界
		for(int i=start;i<=endX;i++) {
			System.out.print(matrix[start][i]+" ");
		}
		for(int i=start+1;i<=endY;i++) {
			System.out.print(matrix[i][endX]+" ");
		}
		for(int i=endX-1;i>=start;i--) {
			System.out.print(matrix[endY][i]+" ");
		}
		for(int i=endY-1;i>=start+1;i--) {
			System.out.print(matrix[i][start]+" ");
		}
		
		//繼續打印更內部的矩陣,令start+1
		printMatrixInCircle(matrix, start+1);
	}
	
	
	public static void main(String[] args) {
		PrintMatrix demo = new PrintMatrix();
		int[][] a= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
//		int[][] a= {};
//		int[][] a= {{}};
//		int[][] a= {{1}};
//		int[][] a= {{1,2,3,4}};
//		int[][] a= {{1},{2},{3},{4}};
//		int[][] a= {{1,2,3},{4,5,6}};
//		int[][] a=null;
		demo.printMatrix(a);
	}

  

  下面的代碼是來自牛客網的C++代碼:1.採用的是循環;2.在打印一圈時,單行或者單列狀況只須要在從右往左打印和從下往上打印時判斷是否會出現重複打印(即後面兩個for循環)。代碼比較簡潔。htm

/*解題思路:順時針打印就是按圈數循環打印,一圈包含兩行或者兩列,在打印的時候會
出現某一圈中只包含一行,要判斷從左向右打印和從右向左打印的時候是否會出現重複打印,
一樣只包含一列時,要判斷從上向下打印和從下向上打印的時候是否會出現重複打印的狀況*/
class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        vector<int>res;
        res.clear();
        int row=matrix.size();//行數
        int collor=matrix[0].size();//列數
        //計算打印的圈數
        int circle=((row<collor?row:collor)-1)/2+1;//圈數
        for(int i=0;i<circle;i++){
            //從左向右打印
            for(int j=i;j<collor-i;j++)
                res.push_back(matrix[i][j]);         
            //從上往下的每一列數據
            for(int k=i+1;k<row-i;k++)
                res.push_back(matrix[k][collor-1-i]);
            //判斷是否會重複打印(從右向左的每行數據)
            for(int m=collor-i-2;(m>=i)&&(row-i-1!=i);m--)
                res.push_back(matrix[row-i-1][m]);
            //判斷是否會重複打印(從下往上的每一列數據)
            for(int n=row-i-2;(n>i)&&(collor-i-1!=i);n--)
                res.push_back(matrix[n][i]);}
        return res;
    }
};

  

收穫

  1.打印一圈矩陣時,注意單行或者單列時是否會重複打印。blog

  2.每一圈矩陣左上角的橫縱座標相等,其他三個角的座標能夠由左上角座標得到。遞歸

  3.打印矩陣的圈數與其列數或者行數的一半有關。簡單但要能想到。

  

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索