力扣hot100:螺旋矩阵(边界压缩,方向模拟)(54)

在解决螺旋矩阵问题时,我们需要按照顺时针螺旋顺序遍历矩阵,并返回所有元素。本文将分享两种高效的解决方案:边界收缩法和方向模拟法。

题目描述

边界收缩法

边界收缩法通过定义四个边界(上、下、左、右)来模拟螺旋遍历的过程。每完成一个方向的遍历,就收缩对应的边界,直到所有元素被访问完毕。

算法思路
  1. 初始化边界top = 0, bottom = m-1(行数-1), left = 0, right = n-1(列数-1)。
  2. 按层遍历
    • 向右 :遍历上边界(top行),从 leftright
    • 向下 :遍历右边界(right列),从 top+1bottom
    • 向左 :遍历下边界(bottom行),从 right-1left+1(需确保存在内层)。
    • 向上 :遍历左边界(left列),从 bottomtop+1(需确保存在内层)。
  3. 收缩边界 :完成一圈后,将 top++, bottom--, left++, right--
  4. 终止条件 :当边界交错时停止(top > bottomleft > right)。
代码实现
java 复制代码
class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> result=new ArrayList<Integer>();

        int x= matrix.length;
        int y=matrix[0].length;

        int left=0;
        int right=y-1;
        int top=0;
        int bottom=x-1;

        while(left<=right&&top<=bottom){

            for(int i=left;i<=right;i++){
                result.add(matrix[top][i]);
            }

            for(int i=top+1;i<=bottom;i++){
                result.add(matrix[i][right]);
            }

            if(left<right&&top<bottom) {
                for (int i = right - 1; i > left; i--) {
                    result.add(matrix[bottom][i]);
                }

                for (int i = bottom; i > top; i--) {
                    result.add(matrix[i][left]);
                }
            }

            left++;
            right--;
            top++;
            bottom--;

        }

        return result;
    }
}
复杂度分析
  • 时间复杂度:O(m*n),每个元素被访问一次。
  • 空间复杂度:O(1),仅使用常量额外空间(结果列表不计入)。

方向模拟法(其他解决方案)

方向模拟法通过定义方向数组和记录访问状态来模拟螺旋路径,适合对边界条件处理不熟悉的情况。

算法思路
  1. 初始化
    • 方向数组 dirs 表示右、下、左、上四个方向。
    • 访问矩阵 visited 记录元素是否被访问。
    • (0,0) 开始,初始方向为右。
  2. 遍历矩阵
    • 将当前元素加入结果列表,并标记为已访问。
    • 计算下一个位置,若越界或已访问,则顺时针转向。
    • 更新位置并继续遍历,直到所有元素被访问。
代码实现
java 复制代码
class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> result = new ArrayList<>();
        if (matrix == null || matrix.length == 0) return result;
        
        int m = matrix.length, n = matrix[0].length;
        boolean[][] visited = new boolean[m][n];
        int[][] dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 右、下、左、上
        int r = 0, c = 0, d = 0;
        int total = m * n;
        
        for (int i = 0; i < total; i++) {
            result.add(matrix[r][c]);
            visited[r][c] = true;
            // 计算下一个位置
            int nr = r + dirs[d][0];
            int nc = c + dirs[d][1];
            // 若越界或已访问,则转向
            if (nr < 0 || nr >= m || nc < 0 || nc >= n || visited[nr][nc]) {
                d = (d + 1) % 4; // 顺时针转向
                nr = r + dirs[d][0];
                nc = c + dirs[d][1];
            }
            r = nr;
            c = nc;
        }
        return result;
    }
}
复杂度分析
  • 时间复杂度:O(m*n),每个元素访问一次。
  • 空间复杂度 :O(m*n),visited 矩阵额外占用空间。

总结

  • 边界收缩法 :通过动态调整边界模拟螺旋路径,无需额外空间,是更优解。
  • 方向模拟法:直观易理解,但需要额外空间记录访问状态,适合快速实现。

两种方法均能高效解决螺旋矩阵问题,实际应用中推荐优先使用边界收缩法!

相关推荐
爱吃烤鸡翅的酸菜鱼20 小时前
深度解析《AI+Java编程入门》:一本为零基础重构的Java学习路径
java·人工智能·后端·ai
SimonKing20 小时前
被卖的Hutool出AI模块了!它如何让Java调用大模型变得如此简单?
java·后端·程序员
不染尘.20 小时前
2025_11_5_刷题
开发语言·c++·vscode·算法·贪心算法·动态规划
不穿格子的程序员20 小时前
从零开始刷算法-栈-字符串解码
java·开发语言
你不是我我20 小时前
【Java 开发日记】设计模式了解吗,知道什么是饿汉式和懒汉式吗?
android·java·开发语言
2501_9291775820 小时前
C++中的虚基类
开发语言·c++·算法
♡喜欢做梦21 小时前
Spring MVC 响应处理:页面、数据与状态配置详解
java·javascript·spring·java-ee
计算机学姐21 小时前
基于SpringBoot的公务员考试管理系统【题库组卷+考试练习】
java·vue.js·spring boot·后端·java-ee·intellij-idea·mybatis
HahaGiver66621 小时前
Unity与Android原生交互开发入门篇 - 打开Android的设置
android·java·unity·游戏引擎·android studio
Blossom.11821 小时前
把AI“贴”进路灯柱:1KB决策树让老旧路灯自己报「灯头松动」
java·人工智能·python·深度学习·算法·决策树·机器学习