二维数组的螺旋矩阵问题

一直在刷LeetCode,也没有放在博客上面,题目太多感觉也没有必要放在这上面。
有兴趣的可以看我的GitHub题解: https://github.com/xdxTao/LeetCode

1、什么是螺旋矩阵呢?

1-1:我们正常的遍历二维数组都是一层一层的遍历。

二维数组的螺旋矩阵问题_第1张图片

1-2:但是螺旋遍历的方式是这样的

二维数组的螺旋矩阵问题_第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

二维数组的螺旋矩阵问题_第3张图片


题解:

  • 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. 螺旋矩阵

二维数组的螺旋矩阵问题_第4张图片


题解:

  • 这题给出的二维数组名称是 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 --;
                    }
                }
            }
        }
    }

你可能感兴趣的:(算法题/数据结构)