幾道與矩陣有關的練習題

1、轉圈打印矩陣

【題目】 給定一個整型矩陣matrix, 請按照轉圈的方式打印它。
例如: 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
【要求】 額外空間複雜度爲O(1)。
思路:如果給出左上方的頂點的座標A(tr,tl),和右下角的點B(dr,dl)
(top row,top line),(down row,down line),這樣可以輕鬆實現打印最外面的所有數字,把這個過程封裝成個函數,然後循環調用。

code

package exercise;
/*
轉圈打印矩陣
 */
class MatCirclePrint {
    private Integer[][]  mat;
    public MatCirclePrint(Integer[][] mat){

        this.mat=mat;
    }
    public void CirclePrintmat(){
        int tr=0,tl=0,dr=mat.length-1,dl=mat[0].length-1;
        while (tr<=dr && tl<=dl){
            printEdge( tr++, tl++, dr--, dl--);
        }

    }

    public void printEdge(Integer tr,Integer tl,Integer dr,Integer dl){
        //tr toprow,dr downrow;[tr,tl]最左上角1的座標,[dr,dl]最右下角
        if (tr==dr){//數據就一行
            while (tl<=dl){
                System.out.print(mat[0][tl]);
                System.out.print(" ");
                tl++;
            }
        }else if (tl==dl){//數據就一列
            while (tr<=dr){
                System.out.println(mat[tr][0]);
                tr++;
            }
        }
        else {
            int curL=tl;//當前走到哪一列了
            int curR=tr;//當前走到哪一行了
            while(curL<dl){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curL++;
            }
            while (curR<dr){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curR++;
            }
            while (curL>tl){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curL--;
            }
            while (curR>tr){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curR--;
            }

        }
    }

    public static void main(String[] args) {
        MatCirclePrint mcp1=new MatCirclePrint(new Integer[][]{{1,2,3,4}});
        mcp1.printEdge(0,0,0,3);
        System.out.println();
        System.out.println("-------------分割線--------------------");
        MatCirclePrint mcp2=new MatCirclePrint(new Integer[][]{{5},{6},{7},{8}});
        mcp2.printEdge(0,0,3,0);
        System.out.println("-------------分割線--------------------");
        MatCirclePrint mcp3=new MatCirclePrint(new Integer[][]{{1, 2, 3, 4},
                                                                {5, 6, 7, 8},
                                                                {9,10,11,12},
                                                                {13,14,15,16}
                                                                });
        System.out.println("printEdge函數測試!");
        mcp3.printEdge(0,0,3,3);
        System.out.println("");
        System.out.println("-------------分割線--------------------");
        System.out.println("測試CirclePrintmat()");
        mcp3.CirclePrintmat();

    }

}

2、旋轉正方形矩陣

旋轉正方形矩陣
【題目】 給定一個整型正方形矩陣matrix, 請把該矩陣調整成
順時針旋轉90度的樣子。
【要求】 額外空間複雜度爲O(1)

package exercise;
/*
轉圈打印矩陣
 */
class Rotate {


    public void rotate(int[][] matrix) {
        int startR=0;
        int startL=0;
        int endR  =matrix.length-1;
        int endL  =matrix[0].length-1;
        while(startR<=endR){
            rotedge(matrix,startR++,startL++,endR--,endL--);
        }
    }
    public void rotedge(int[][]matrix,int topRow,int topLine,int downRow,int downLine ){
        int tem=0;
        int times=downLine-topLine;
        for(int i=1;i<=times;i++){
            tem=matrix[topRow][topLine+i];
            matrix[topRow][topLine+i]=matrix[downRow-i][topLine];
            matrix[downRow-i][topLine]=matrix[downRow][downLine-i];
            matrix[downRow][downLine-i]=matrix[topLine+i][downLine];
            matrix[topLine+i][downLine]=tem;

        }
    }

}

3、之” 字形打印矩陣

“之” 字形打印矩陣
【題目】 給定一個矩陣matrix, 按照“之” 字形的方式打印這
個矩陣, 例如:
1 2 3 4
5 6 7 8
9 10 11 12
“之” 字形打印的結果爲: 1, 2, 5, 9, 6, 3, 4, 7, 10, 11,
8, 12
【要求】 額外空間複雜度爲O(1)
思路:構建A,B兩個點,A點一直右移,走到最右端下移;
   B點一直下移,走到最下端右移;
   一直打印A,B兩點連線上的數據

   

代碼如下:

package exercise;
 class PrintZhiMat{
    public void printZhimat(int[][]arr){
        int tem_ar=0;
        int tem_al=0;
        int tem_br=0;
        int tem_bl=0;
        int count=0;
        while (tem_ar!=arr.length ){
            //循環終止條件,A來到最後一行
            printdiagonal(arr,tem_ar,tem_al,tem_br,tem_bl,count%2);
            //下面的判斷寫成三目運算符更好
            if (tem_al<arr[0].length-1){
                tem_al++;
            }else {
                tem_ar++;
            }
            if (tem_br<arr.length-1){
                tem_br++;
            }
            else {
                tem_bl++;
            }
            count++;
            //System.out.printf("這是第%d次循環",count++);

        }


    }
public void  printdiagonal(int[][] arr,int ar,int al,int br,int bl,int flag){
        //A(ar,al),B(br,bl)
        int tem_ar=ar;
        int tem_al=al;
        int tem_br=br;
        int tem_bl=bl;
        if (flag==0){
            while (tem_ar<=tem_br){
                System.out.print(arr[tem_br--][tem_bl++]);
                System.out.print(" ");
            }
        }
        if (flag==1){
            while (tem_ar<=tem_br){
                System.out.print(arr[tem_ar++][tem_al--]);
                System.out.print(" ");
            }
        }

    }


    public static void main(String[] args) {
        int[][] mat=new int[][]{{1,2,3,4},
                                {5,6,7,8},
                                {9,10,11,12},
                                {13,14,15,16} };
        PrintZhiMat pzt =new PrintZhiMat();
        pzt.printdiagonal(mat,0,3,3,0,0);
        System.out.println("\n----------------分割線-----------------");
        pzt.printdiagonal(mat,0,3,3,0,1);
        System.out.println("\n----------------分割線-----------------");
        pzt.printZhimat(mat);
    }

}

執行結果

13 10 7 4 
----------------分割線------------------------
4 7 10 13 
----------------分割線------------------------
1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16 

4 在已排好序的矩陣中查找數字

【題目】 給定一個有N*M的整型矩陣matrix和一個整數K,matrix的每一行和每一 列都是排好序的。 實現一個函數, 判斷K是否在matrix中。 例如:
            0 1 2 5
            2 3 4 7
            4 4 4 8
            5 7 7 9
 如果K爲7, 返回true; 如果K爲6, 返回false。
【要求】 時間複雜度爲O(N+M), 額外空間複雜度爲O(1)
思路:
 選取左下角(或右上角)的點mat[mat.length-1][0]作爲起點;
 當前的數比K小則向右走;
 當前的數比K大則向上走;
 臨界條件,遍歷的數走出mat

public class e8_findNumOrdered {


    public boolean findNumOrdered(int[][] mat, int K){
        int i=mat.length-1,j=0;
        while (i<mat.length  &&  j<mat[0].length){

            if (mat[i][j]==K){
                return true;
            }
            else if (mat[i][j]>K){
                i--;
            }else {
                j++;
            }

        }

        return false;
    }

    public static void main(String[] args) {
        int [][]arr={
                {1,3,5,7,9},
                {3,4,6,17,10},
                {9,11,12,20,35},
                {40,41,56,70,100}
        };
        e8_findNumOrdered  fno=new e8_findNumOrdered ();
        System.out.println(fno.findNumOrdered(arr,9));

    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章