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


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

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

題目 

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

思路

  每次打印矩陣最外面的一圈(用方法printMatrixInCircle()表示),每次都是這個操作,所以可以采用遞歸。每次打印矩陣的左上角的橫縱坐標相同,即為start,而其余三個角的坐標都與行列數以及start有關,因此只需要for循環即可實現打印。

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

測試算例 

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

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循環)。代碼比較簡潔。

/*解題思路:順時針打印就是按圈數循環打印,一圈包含兩行或者兩列,在打印的時候會
出現某一圈中只包含一行,要判斷從左向右打印和從右向左打印的時候是否會出現重復打印,
同樣只包含一列時,要判斷從上向下打印和從下向上打印的時候是否會出現重復打印的情況*/
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.打印一圈矩陣時,注意單行或者單列時是否會重復打印。

  2.每一圈矩陣左上角的橫縱坐標相等,其余三個角的坐標可以由左上角坐標獲得。

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

  

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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM