天天看點

【Java】【算法練習】對于一個矩陣,請設計一個算法從左上角(mat[0][0])開始,順時針列印矩陣元素。 給定int矩陣mat,以及它的維數nxm,請傳回一個數組,數組中的元素為矩陣元素的順時針輸

題目描述:

對于一個矩陣,請設計一個算法從左上角(mat[0][0])開始,順時針列印矩陣元素。

給定int矩陣mat,以及它的維數nxm,請傳回一個數組,數組中的元素為矩陣元素的順時針輸出。

測試樣例:

[[1,2],[3,4]],2,2

傳回:[1,2,4,3]

解題思路:

對于一個矩陣,順時針列印時一定要保證邊界處理的正确性;

解題代碼:

public class Printer {
    public int[] clockwisePrint(int[][] mat, int n, int m) {
        // write code here
        // 定義一個傳回結果的數組,将順時針周遊的所有值存下來傳回
        int[] ret = new int[m*n];   // n為行,m為列
        // 判斷非法輸入的情況
        if(n <= 0 || m <= 0)
            return ret;

        // 定義控制行的下标
        int i = 0;
        // 定義控制列的下标
        int j = 0;
        // 定義控制要傳回的數組ret的下标
        int index = 0;
        // 定義圈數,每周遊完一層就 +1
        int N = 0;
        // 當要傳回的數組的下标超過 n*m 時,說明數組已經滿了,也就是給定的mat數組中所有的數都已 
        //經周遊完了,此時結束
        while(index < ret.length) {

            // 向右列印,列++,行不動,列 < 總列數-圈數,可以有效的控制列印的列下标
            while(j < m-N && index < ret.length) {
                ret[index] = mat[i][j];
                index++;
                j++;
            }

            // 向下列印
            // 要豎着列印的第一個元素上一個橫着向右列印已經周遊過了,是以 i++,來到下一行
            i++;
            // 由于上面的橫着向右列印最後結束的位置在 mat[i][m - N],這裡已經越界,是以要進行j--
            j--;
            // 行++,列不動,行 < 總行數-圈數
            while(i < n-N && index < ret.length) {
                ret[index] = mat[i][j];
                index++;
                i++;
            }

            // 向左列印
            j--;
            i--;
            // j >= N 和上面的道理是一樣的,可以帶個值進行驗證一下,比第一圈(N = 0), 是以向左 
            //周遊要到第一列(下标是0)的位置
            while(j >= N && index < ret.length) {
                ret[index] = mat[i][j];
                j--;
                index++;
            }

            // 向上列印
            j++;
            i--;
            // 注意這裡沒有等号,比如 第一圈(N = 0),第一行(下标為0)的位置已經列印過了
            while(i > N && index < ret.length) {
                ret[index] = mat[i][j];
                i--;
                index++;
            }

            // 一圈已經周遊完了,就來到下一圈
            N++;
            // 行和列的下标都要 +1,往裡走一圈
            i++;
            j++;
        }
        // 傳回結果
        return ret;
    }
}