LeetCode hot 100 每日一题(14)——54.螺旋矩阵

devtools/2025/3/26 4:18:59/

这是一道难度为中等的题目,让我们来看看题目描述:

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
请添加图片描述

请添加图片描述

提示:

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

题解

解题的核心思路是按照右、下、左、上的顺序遍历数组,并使用四个变量圈定未遍历元素的边界
请添加图片描述

随着螺旋遍历,相应的边界会收缩,直到螺旋遍历完整个数组:
请添加图片描述

class Solution {public List<Integer> spiralOrder(int[][] matrix) {// 获取矩阵的行数和列数int m = matrix.length;         // 行数int n = matrix[0].length;      // 列数// 定义遍历未处理区域的边界:// upper_bound:上边界,初始为第一行(索引0)// lower_bound:下边界,初始为最后一行(索引 m - 1)int upper_bound = 0, lower_bound = m - 1;// left_bound:左边界,初始为第一列(索引0)// right_bound:右边界,初始为最后一列(索引 n - 1)int left_bound = 0, right_bound = n - 1;// 创建一个链表用来保存最终的螺旋顺序遍历结果List<Integer> res = new LinkedList<>();// 当结果列表的元素个数还没有达到整个矩阵的元素总数时,继续遍历while (res.size() < m * n) {// 从左到右遍历上边界这一行// 前提条件:upper_bound <= lower_bound确保当前行未超出下边界if (upper_bound <= lower_bound) {for (int j = left_bound; j <= right_bound; j++) {res.add(matrix[upper_bound][j]);  // 将上边界行的元素依次添加}upper_bound++;  // 上边界向下移动一行,因为当前行已遍历}// 从上到下遍历右边界这一列// 前提条件:left_bound <= right_bound确保当前列未超出左边界if (left_bound <= right_bound) {for (int i = upper_bound; i <= lower_bound; i++) {res.add(matrix[i][right_bound]);  // 将右边界列的元素依次添加}right_bound--;  // 右边界向左移动一列,因为当前列已遍历}// 从右到左遍历下边界这一行// 前提条件:upper_bound <= lower_bound确保当前行未超出上边界if (upper_bound <= lower_bound) {for (int j = right_bound; j >= left_bound; j--) {res.add(matrix[lower_bound][j]);  // 将下边界行的元素依次添加}lower_bound--;  // 下边界向上移动一行,因为当前行已遍历}// 从下到上遍历左边界这一列// 前提条件:left_bound <= right_bound确保当前列未超出右边界if (left_bound <= right_bound) {for (int i = lower_bound; i >= upper_bound; i--) {res.add(matrix[i][left_bound]);   // 将左边界列的元素依次添加}left_bound++;  // 左边界向右移动一列,因为当前列已遍历}}// 返回包含所有元素的螺旋顺序结果列表return res;}
}

总结

这道题目的解法对我来说有一些难以理解,那么直接强制记忆:

你可以试着将这个螺旋遍历过程拆分成四个简单的步骤,每一步只关注一个方向,并记住一个顺时针的遍历顺序:从左到右、从上到下、从右到左、从下到上。下面几个记忆小技巧可能对你有帮助:

  1. 分块记忆:
    想象矩阵就像一层层的“洋葱皮”。每一层的遍历就是围绕这个“洋葱”走一圈,你只需要记住当前层的边界,然后按照顺时针方向依次执行四个步骤。

  2. 口诀法:
    你可以编一个简单的口诀,比如“左到右,上到底,右到左,下到上”。每完成一圈后,再调整边界,重复这个过程。

  3. 边界的概念:
    四个变量(upper_bound、lower_bound、left_bound、right_bound)就像四道“防线”。每次遍历一条边之后,你就“消耗”掉这一行或这一列,然后更新边界。记住:

    • 遍历上边界后,upper_bound++

    • 遍历右边界后,right_bound–

    • 遍历下边界后,lower_bound–

    • 遍历左边界后,left_bound++

  4. 可视化思维:
    在心里或纸上画出一个矩阵,并用箭头标注出遍历的方向。通过不断的练习,你会发现这种螺旋移动方式会越来越直观。


http://www.ppmy.cn/devtools/171249.html

相关文章

Qemu-STM32(十):STM32F103开篇

简介 本系列博客主要描述了STM32F103的qemu模拟器实现&#xff0c;进行该项目的原因有两点: 作者在高铁上&#xff0c;想在STM32F103上验证一个软件框架时&#xff0c;如果此时掏出开发板&#xff0c;然后接一堆的线&#xff0c;旁边的人估计会投来异样的目光&#xff0c;特别…

K8s 跨集群通信的“量子纠缠”:当 DNS 黑洞吞没你的服务请求

引言 对于这种案例&#xff0c;你们的处理思路是怎么样的呢&#xff0c;是否真正的处理过&#xff0c;如果遇到&#xff0c;你们应该怎么处理。 我想大多数人都没有遇到过。 开始 一、现象&#xff1a;跨集群通信的神秘失效 某金融系统在混合云架构中部署了多套 Kubernete…

【Linux文件IO】通过文件IO把bmp图片显示到Linux开发板的实现

通过文件IO把bmp图片显示到Linux开发板的实现 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h>/* 显示24位的BMP图片特点1:每…

java项目之基于ssm的游戏攻略网站(源码+文档)

项目简介 游戏攻略网站实现了以下功能&#xff1a; 管理员主要负责填充图书和其类别信息&#xff0c;并对已填充的数据进行维护&#xff0c;包括修改与删除&#xff0c;管理员也需要审核老师注册信息&#xff0c;发布公告信息&#xff0c;管理自助租房信息等。 &#x1f495;…

判断是不是完全二叉树(C++)

目录 1 问题描述 1.1 示例1 1.2 示例2 1.3 示例3 2 解题思路 3 代码实现 4 代码解析 4.1 定义队列&#xff0c;初始化根节点 4.2 层序遍历&#xff0c;处理每个节点 4.3 处理空节点 4.4 处理非空节点 5 总结 1 问题描述 给定一个二叉树&#xff0c;确定他是否是一…

学习记录-Ajax-自封装axios函数

目录 自封装axios函数封装axios函数实现步骤1. 准备阶段2. 实现无参get请求3.实现有参get请求4. 实现post请求 完整实例代码 自封装axios函数 封装axios函数实现步骤 1. 准备阶段 理解axios函数的底层原理&#xff0c;包括Promise,XMLHttpRequest等概念 XMLHttpRequest工作…

贪心算法(11)(java)加油站

题目&#xff1a;在一条环路上有n个加油站&#xff0c;其中第i个加油站有汽油 gas[i]升.。 你有一辆油箱容量无限的的汽车&#xff0c;从第i个加油站开往第i1个加油站需要消耗汽油 cost[i]升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定…

Spring Security核心源码和功能实现

Spring Security 是一个强大的安全框架,用于保护基于 Spring 的应用程序。它提供了认证、授权、防止常见安全攻击等功能。下面是对 Spring Security 的核心功能和实现的详细分析,并使用 Mermaid 绘制相关流程图。 1. 核心功能 1.1 认证(Authentication) 用户认证:验证用…