栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

LeetCode 54. 螺旋矩阵 && 59. 螺旋矩阵 II(中等、数组)day24

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LeetCode 54. 螺旋矩阵 && 59. 螺旋矩阵 II(中等、数组)day24

54. 螺旋矩阵: 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100

方法解析:模拟访问二维数组方向解法: (1)左 -> 右 (2)上 -> 下 (3)右 -> 左 (4)下 -> 上

动画显示参考连接:https://leetcode.cn/problems/spiral-matrix/solution/dong-hua-mo-ni-yi-xia-jiu-neng-gao-dong-i27qf/

  int top = 0, bottom = row - 1;  // 定义上下边界
  int left = 0, right = column - 1; // 定义左右边界

        while (true){

            // 遍历二维数组的上边  行不变   列变化
            for(int i = left; i <= right; i++){
                ans[index++] = matrix[top][i];
            }
            top++;  // 当前行遍历完全,移动到下一行
            if(top > bottom) break;  // 循环结束标志,这里不能取等号

            // 遍历二维数组的右边  行变化  列不变
            for(int i = top; i <= bottom; i++){
                ans[index++] = matrix[i][right];
            }
            right--;  // 右边遍历完全 向左边靠拢
            if(right < left) break;


            // 遍历二维数组的下边 行不变 列变化
            for(int i = right; i >= left; i--){
                ans[index++] = matrix[bottom][i];
            }
            bottom--;  // 下边遍历完全,向上移动
            if(bottom < top) break;


            // 遍历二维数组的左边 行变化 列不变
            for(int i = bottom; i >= top; i--){
                ans[index++] = matrix[i][left];
            }
            left++;  // 左边遍历完全 向左移动
            if(left > right) break;
        }

代码实现:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SpiralOrderDemo {
    public static void main(String[] args) {
//        int[][] matrix = {{1,2,3},{4,5,6},{7,8,9}};
        int[][] matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};

        int[] ans = spiralOrder1(matrix);
        System.out.println(Arrays.toString(ans));

        List list = spiralOrder2(matrix);
        System.out.println(list);
    }

    
    public static int[] spiralOrder1(int[][] matrix){
        int row = matrix.length;  // 二维矩阵的行数
        if(row == 0 || matrix == null){
            return new int[]{}; // 空数组
        }

        int column = matrix[0].length; // 二维矩阵的列数

        int[] ans = new int[row * column];  // 定义返回数组---大小为row * column
        int index = 0; // ans数组下标

        int top = 0, bottom = row - 1;  // 定义上下边界
        int left = 0, right = column - 1; // 定义左右边界

        while (true){

            // 遍历二维数组的上边  行不变   列变化
            for(int i = left; i <= right; i++){
                ans[index++] = matrix[top][i];
            }
            top++;
            if(top > bottom) break;



            // 遍历二维数组的右边  行变化  列不变
            for(int i = top; i <= bottom; i++){
                ans[index++] = matrix[i][right];
            }
            right--;  // 右边遍历完全 向左边靠拢
            if(right < left) break;


            // 遍历二维数组的下边 行不变 列变化
            for(int i = right; i >= left; i--){
                ans[index++] = matrix[bottom][i];
            }
            bottom--;  // 下边遍历完全,向上移动
            if(bottom < top) break;


            // 遍历二维数组的左边 行变化 列不变
            for(int i = bottom; i >= top; i--){
                ans[index++] = matrix[i][left];
            }
            left++;  // 左边遍历完全 向左移动
            if(left > right) break;
        }

        return ans;
    }


    
    public static List spiralOrder2(int[][] matrix){
       List ans = new ArrayList<>();
       int m = matrix.length, n = matrix[0].length;
       circle(matrix, 0, 0, m-1, n-1, ans);
       return ans;
    }
    static void circle(int[][] matrix, int x1, int y1, int x2, int y2, List ans){
        if(x2 < x1 || y2 < y1){
            return;
        }

        // 只有一行时, 按照行进行遍历
        if(x1 == x2){
            for(int i = y1; i <= y2; i++){
                ans.add(matrix[x1][i]);
            }
            return;
        }

        // 只有一列时, 按照列进行遍历
        if(y1 == y2){
            for(int i = x1; i <= x2; i++){
                ans.add(matrix[i][y1]);
            }
            return;
        }

        // 遍历当前圈
        for(int i = y1; i < y2; i++)  ans.add(matrix[x1][i]);
        for(int i = x1; i < x2; i++)  ans.add(matrix[i][y2]);
        for(int i = y2; i > y1; i--)  ans.add(matrix[x2][i]);
        for(int i = x2; i > x1; i--)  ans.add(matrix[i][y1]);

        // 往里收一圈,继续遍历
        circle(matrix, x1 + 1, y1 + 1, x2 - 1, y2 -1, ans);
    }
}

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

59. 螺旋矩阵 II: 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

输入:n = 1
输出:[[1]]

方法解析:

本题和螺旋矩阵非常相像,也可以理解成其进阶版,只要会了螺旋矩阵的访问方式就可以做本题。
 public static int[][] generateMatrix(int n){
        int[][] ans = new int[n][n];

        int left = 0, right = n - 1;  // 二维数组左右边界
        int top = 0, bottom = n - 1;  // 二维数组上下边界
        int value = 1;

        while (true){
            // 上边
            for(int i = left; i <= right; i++){
                ans[top][i]  = value;  // 唯一改动的地方
                value++;
            }
            top++;
            if(top > bottom) break;


            // 右边
            for(int i = top; i <= bottom; i++){
                ans[i][right] = value;
                value++;
            }
            right--;
            if(right < left) break;


            // 下边
            for(int i = right; i >= left; i--){
                ans[bottom][i] = value;
                value++;
            }
            bottom--;
            if(top > bottom) break;


            // 左边
            for(int i = bottom; i >= top; i--){
                ans[i][left] = value;
                value++;
            }
            left++;
            if(left > right) break;

        }

        return ans;
    }

总结:
按照题目的要求发现该遍历方式很好理解,但是难点就在于对于边界的处理,通过参考别人写的题解发现要设置上下两个边界top = 0、bottom = row - 1, 左右两个边界 left = 0 和 right = column - 1。
当访问数组上边界后要进行top++操作,表示当前上边界已经遍历完全,还要进行top与bottom判断,循环结束的条件为top > bottom;
当访问数组有边界后要进行right--操作,表示当前右边界已经遍历完全,还要进行left与right判断,循环结束的条件为left > bottom;
当访问数组下边界后要进行bottom--操作,表示当前下边界已经遍历完全,还要进行top与bottom判断,循环结束的条件为top > bottom;
当访问数组左边界后要进行left操作,表示当前左边界已经遍历完全,还要进行left与right判断,循环结束的条件为left > bottom;

此题的解题技巧可以背下来!!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/877647.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号