二維數組的螺旋矩陣問題

一直在刷LeetCode,也沒有放在博客上面,題目太多感覺也沒有必要放在這上面。
有興趣的可以看我的GitHub題解: https://github.com/xdxTao/LeetCode

1、什麼是螺旋矩陣呢?

1-1:我們正常的遍歷二維數組都是一層一層的遍歷。

在這裏插入圖片描述

1-2:但是螺旋遍歷的方式是這樣的

在這裏插入圖片描述


2、解題思路

2-1:遍歷的方式是:我們每次只移動 i、j,其中一個,並且一直移動到底。

2-2:我們需要考慮每一個臨界點上的變化。

2-3:我們可以定義三個變量來輔助我們判斷

  • int moveFlag = ‘j’; (當moveFlag=i,的時候是移動 i,否則移動 j)
  • char jDir = ‘→’; (j 移動的方向,用這種箭頭太直接了,哈哈)
  • char iDir = ‘↓’; (同理 i,的移動方向)

3、舉例(下面以leetcode上面兩個題爲例)

59. 螺旋矩陣 II

在這裏插入圖片描述


題解:

  • new 一個空數組裏面每一個默認數據都是0 ,(我將返回的數組命名爲 result)
  • 到達右邊界 : j+1 >= n || result[i][j+1] != 0
  • 到達左邊界 : j-1 < 0 || result[i][j-1] != 0
  • 到達下邊界 : i+1 >= n || result[i+1][j] != 0
  • 到達上邊界 : i-1 < 0 || result[i-1][j] != 0
  • 其實也很好理解,就是判斷是否 超出數組範圍、和已經賦過值

代碼:

    public int[][] generateMatrix(int n) {
        if (n <= 0){
            return new int[][]{};
        }
        int[][] result = new int[n][n];
        int i = 0,j = 0;
        int moveFlag = 'j';
        char jDir = '→';
        char iDir = '↓';
        int cur = 1;
        while (cur <= n * n){

            result[i][j] = cur;
            if (moveFlag == 'j'){
                if (jDir == '→'){
                    // 到達了右邊界
                    if (j+1 >= n || result[i][j+1] != 0){
                        // 這時,我們應該讓i,向下
                        moveFlag = 'i';
                        iDir = '↓';
                        i ++;
                    }else{
                        j++;
                    }
                }else{
                    // 到達了左邊界
                    if (j-1 < 0 || result[i][j-1] != 0){
                        // 這時,我們應該讓i,向上
                        moveFlag = 'i';
                        iDir = '↑';
                        i --;
                    }else {
                        j --;
                    }
                }
            }else {
                if (iDir == '↓'){
                    // 到了下邊界
                    if (i+1 >= n || result[i+1][j] != 0){
                        // 這時候,我們應該讓j,向左
                        moveFlag = 'j';
                        jDir = '←';
                        j --;
                    }else{
                        i ++;
                    }
                }else {
                    // 到達了上邊界
                    if (i-1 < 0 || result[i-1][j] != 0){
                        // 這時候,我們應該讓j,向右
                        moveFlag = 'j';
                        jDir = '→';
                        j ++;
                    }else{
                        i --;
                    }
                }
            }
        }
        return result;
    }




54. 螺旋矩陣

在這裏插入圖片描述


題解:

  • 這題給出的二維數組名稱是 matrix,因爲數組數據可能是0,所以我們這次用 Integer.MAX_VALUE 來輔助判斷
  • 到達右邊界 : j+1 >= m || matrix[i][j+1] == Integer.MAX_VALUE
  • 到達左邊界 : j-1 < 0 || matrix[i][j-1] == Integer.MAX_VALUE
  • 到達下邊界 : i+1 >= n || matrix[i+1][j] == Integer.MAX_VALUE
  • 到達上邊界 : i-1 < 0 || matrix[i-1][j] == Integer.MAX_VALUE
  • 就是判斷是否 超出數組範圍、和是否已經遍歷過了 (遍歷過的 Integer.MAX_VALUE)

代碼:


    public List<Integer> spiralOrder(int[][] matrix) {

        if (matrix == null || (matrix.length == 0 || matrix[0].length == 0)){
            return new ArrayList<>();
        }
        int n = matrix.length;
        int m = matrix[0].length;
        int i = 0,j = 0;
        int moveFlag = 'j';
        char jDir = '→';
        char iDir = '↓';
        List<Integer> result = new ArrayList<>();
        while (true){

            result.add(matrix[i][j]);
   
            matrix[i][j] = Integer.MAX_VALUE;

            if (
		(i-1 < 0 || matrix[i-1][j] == Integer.MAX_VALUE) && 
		(i+1 >= n || matrix[i+1][j] == Integer.MAX_VALUE) && 
		(j - 1 < 0 || matrix[i][j-1] == Integer.MAX_VALUE) && 
		(j+1 >= m || matrix[i][j+1] == Integer.MAX_VALUE)){

                return result;
            }


            if (moveFlag == 'j'){
                if (jDir == '→'){
                    // 到達了右邊界
                    if (j+1 >= m || matrix[i][j+1] == Integer.MAX_VALUE){
                        // 這時,我們應該讓i,向下
                        moveFlag = 'i';
                        iDir = '↓';
                        i ++;
                    }else{
                        j++;
                    }
                }else{
                    // 到達了左邊界
                    if (j-1 < 0 || matrix[i][j-1] == Integer.MAX_VALUE){
                        // 這時,我們應該讓i,向上
                        moveFlag = 'i';
                        iDir = '↑';
                        i --;
                    }else {
                        j --;
                    }
                }
            }else {
                if (iDir == '↓'){
                    // 到了下邊界
                    if (i+1 >= n || matrix[i+1][j] == Integer.MAX_VALUE){
                        // 這時候,我們應該讓j,向左
                        moveFlag = 'j';
                        jDir = '←';
                        j --;
                    }else{
                        i ++;
                    }
                }else {
                    // 到達了上邊界
                    if (i-1 < 0 || matrix[i-1][j] == Integer.MAX_VALUE){
                        // 這時候,我們應該讓j,向右
                        moveFlag = 'j';
                        jDir = '→';
                        j ++;
                    }else{
                        i --;
                    }
                }
            }
        }
    }

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