leetcode--螺旋矩阵

LCR 146.螺旋遍历二维数组

给定一个二维数组 array,请返回「螺旋遍历」该数组的结果。

螺旋遍历:从左上角开始,按照 向右向下向左向上 的顺序 依次 提取元素,然后再进入内部一层重复相同的步骤,直到提取完所有元素。

示例 1:

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

示例 2:

输入:array  = [[1,2,3,4],[12,13,14,5],[11,16,15,6],[10,9,8,7]]
输出:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]

限制:

  • 0 <= array.length <= 100
  • 0 <= array[i].length <= 100

原理

  1. 初始化边界:

    • north, south, east, west 分别表示二维数组的上、下、右、左边界。开始时,north = 0, south = array.length - 1, east = array[0].length - 1, west = 0,即全覆盖数组的外边界。
  2. 螺旋遍历:

    • 螺旋遍历从左上角(north, west)开始,顺时针按“右、下、左、上”的顺序遍历二维数组。

    • 第一步: 从左到右遍历,即遍历当前的北边界行。

    • 第二步: 从上到下遍历,即遍历当前的东边界列。

    • 第三步: 从右到左遍历,即遍历当前的南边界行。

    • 第四步: 从下到上遍历,即遍历当前的西边界列。

    每一轮螺旋遍历后,都会减少遍历区域的边界:

    • north++:上边界下移
    • west++:左边界右移
    • south--:下边界上移
    • east--:右边界左移

    这样,每完成一圈遍历,内层的元素逐步被收录,直到所有元素都被遍历完。

  3. 终止条件:

    • sum(剩余未遍历元素的数量)为 0 时,表示所有元素都已被访问完,跳出循环。
  4. 返回结果:

    • 最终,list 数组包含了螺旋遍历的所有元素,按顺序返回。

时间复杂度:

  • 假设数组的维度是 m x n,遍历所有元素的时间复杂度是 O(m * n),因为每个元素都只会被访问一次。

空间复杂度:

  • 空间复杂度为 O(m * n),因为需要一个大小为 m * n 的数组来存储遍历的结果。

代码 

class Solution {public int[] spiralArray(int[][] array) {// 获取二维数组的行数,即南边界int south = array.length - 1;  // 如果数组没有行,直接返回空数组if (south == -1) {return new int[0];}// 获取二维数组的列数,即东边界int east = array[0].length - 1;  // 如果数组没有列,直接返回空数组if (east == -1) {return new int[0];}// 计算二维数组中的总元素个数,决定返回数组的大小int sum = (south + 1) * (east + 1);  // 初始化边界int north = 0, west = 0;// 创建存储结果的数组int[] list = new int[sum];// count 用来记录当前插入的位置int count = 0;// 开始螺旋遍历while (sum > 0) {// 从左到右遍历(沿着北边界)for (int i = west; i <= east; i++) {list[count++] = array[north][i];  // 将当前元素加入结果数组sum--;  // 每遍历一个元素,减去一个}// 如果所有元素已经遍历完,跳出循环if (sum == 0) {break;}// 从上到下遍历(沿着东边界)for (int i = north + 1; i <= south; i++) {list[count++] = array[i][east];  // 将当前元素加入结果数组sum--;  // 每遍历一个元素,减去一个}// 如果所有元素已经遍历完,跳出循环if (sum == 0) {break;}// 从右到左遍历(沿着南边界)for (int i = east - 1; i >= west; i--) {list[count++] = array[south][i];  // 将当前元素加入结果数组sum--;  // 每遍历一个元素,减去一个}// 如果所有元素已经遍历完,跳出循环if (sum == 0) {break;}// 从下到上遍历(沿着西边界)for (int i = south - 1; i > north; i--) {list[count++] = array[i][west];  // 将当前元素加入结果数组sum--;  // 每遍历一个元素,减去一个}// 更新边界,进入内层north++;west++;south--;east--;}// 返回螺旋遍历的结果return list;}
}

 54.螺旋矩阵

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

示例 1:

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

示例 2:

输入: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. 初始化边界:

    • north, south, east, west 分别表示二维数组的上、下、右、左边界。开始时,north = 0, south = matrix.length - 1, east = matrix[0].length - 1, west = 0,即全覆盖矩阵的外边界。
  2. 螺旋遍历:

    • 螺旋遍历从左上角(north, west)开始,顺时针按“右、下、左、上”的顺序遍历二维矩阵中的元素。

    • 第一步: 从左到右遍历,即遍历当前的北边界行。

    • 第二步: 从上到下遍历,即遍历当前的东边界列。

    • 第三步: 从右到左遍历,即遍历当前的南边界行。

    • 第四步: 从下到上遍历,即遍历当前的西边界列。

    每完成一圈螺旋遍历后,都会更新边界:

    • north++:上边界下移
    • west++:左边界右移
    • south--:下边界上移
    • east--:右边界左移

    这样,每完成一圈遍历,内层的元素逐步被收录,直到所有元素都被遍历完。

  3. 终止条件:

    • sum(剩余未遍历元素的数量)为 0 时,表示所有元素都已被访问完,跳出循环。
  4. 返回结果:

    • 最终,list 列表包含了矩阵的螺旋顺序遍历结果,按顺序返回。

时间复杂度:

  • 假设矩阵的维度是 m x n,遍历所有元素的时间复杂度是 O(m * n),因为每个元素只会被访问一次。

空间复杂度:

  • 空间复杂度为 O(m * n),因为需要一个大小为 m * n 的列表来存储遍历的结果。

代码 

class Solution {public List<Integer> spiralOrder(int[][] matrix) {// 获取矩阵的南边界(即最后一行的索引)int south = matrix.length - 1;// 获取矩阵的东边界(即最后一列的索引)int east = matrix[0].length - 1;// 计算矩阵中元素的总数int sum = (south + 1) * (east + 1);// 初始化边界,north 是上边界,west 是左边界int north = 0, west = 0;// 用一个列表来存储螺旋遍历的结果List<Integer> list = new ArrayList<>(south * east);// 螺旋遍历开始,直到所有元素都被访问while (sum > 0) {// 1. 从左向右遍历(沿着北边界)for (int i = west; i <= east; i++) {list.add(matrix[north][i]);  // 将当前元素加入结果列表sum--;  // 减少未访问的元素数目}// 如果所有元素已经遍历完,退出循环if (sum == 0) {break;}// 2. 从上到下遍历(沿着东边界)for (int i = north + 1; i <= south; i++) {list.add(matrix[i][east]);  // 将当前元素加入结果列表sum--;  // 减少未访问的元素数目}// 如果所有元素已经遍历完,退出循环if (sum == 0) {break;}// 3. 从右向左遍历(沿着南边界)for (int i = east - 1; i >= west; i--) {list.add(matrix[south][i]);  // 将当前元素加入结果列表sum--;  // 减少未访问的元素数目}// 如果所有元素已经遍历完,退出循环if (sum == 0) {break;}// 4. 从下到上遍历(沿着西边界)for (int i = south - 1; i > north; i--) {list.add(matrix[i][west]);  // 将当前元素加入结果列表sum--;  // 减少未访问的元素数目}// 更新边界,进入内层north++;  // 上边界下移west++;   // 左边界右移south--;  // 下边界上移east--;   // 右边界左移}// 返回螺旋遍历的结果return list;}
}

59.螺旋矩阵II

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= n <= 20

原理

  1. 初始化:

    • 我们首先创建一个大小为 n x n 的矩阵 ans
    • sum 变量记录当前要填充的数字,从 1 开始递增。
    • 使用 rowcolumn 变量来指示当前的矩阵填充位置。
  2. 螺旋顺序填充:

    • 每一圈的填充包括四个方向:向右、向下、向左、向上,依次填充矩阵的边界。
    • 向右: 从当前的 (row, column) 开始,向右填充 n 个位置。
    • 向下: 在完成右边的填充后,向下填充 n-1 个位置。
    • 向左: 完成下边的填充后,向左填充 n-2 个位置。
    • 向上: 完成左边的填充后,向上填充 n-3 个位置。

    每次一圈填充后,更新边界,将 n 减少 2,以保证下一圈填充在内层矩阵中进行。

  3. 边界收缩:

    • 每次完成一圈的填充后,column++ 将列向右移动,准备进行下次填充。
    • 同时 n -= 2,表示当前有效矩阵的边长减少 2,从而让填充继续进行到内层。
  4. 终止条件:

    • n <= 0 时,表示已经填充完所有的元素,退出循环并返回结果矩阵。

时间复杂度:

  • 假设矩阵的大小为 n x n,所有元素都需要被遍历一次并填充。因此时间复杂度为 O(n²)

空间复杂度:

  • 需要一个 n x n 的矩阵来存储结果,因此空间复杂度为 O(n²)

代码

class Solution {public int[][] generateMatrix(int n) {// 初始化一个 n x n 的矩阵int[][] ans = new int[n][n];// sum 用来记录当前填充的数字,初始为 1int sum = 1;// row 和 column 用来记录当前要填充的位置的行和列int row = 0, column = 0;// 只要 n > 0,就继续填充while (n > 0) {// 1. 从左到右填充当前的北边界for (int i = 0; i < n; i++) {ans[row][column++] = sum++;  // 填充当前元素,并将列加 1}// 向左回退一列,因为 column++ 会使列超出范围column -= 1;// 2. 从上到下填充当前的东边界for (int i = 0; i < n - 1; i++) {ans[++row][column] = sum++;  // 填充当前元素,并将行加 1}// 3. 从右到左填充当前的南边界for (int i = n - 2; i >= 0; i--) {ans[row][--column] = sum++;  // 填充当前元素,并将列减 1}// 4. 从下到上填充当前的西边界for (int i = n - 2; i > 0; i--) {ans[--row][column] = sum++;  // 填充当前元素,并将行减 1}// 回到上边界的下一列,并且减少矩阵的规模(边界收缩)column++;n -= 2;  // 每一圈填充完成后,矩阵的有效边长减少 2}// 返回生成的矩阵return ans;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/483668.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 分治

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 1.分治法 2.二分搜索 函数传参——数组 3.棋盘覆盖 4.合并排序 5.快速排序 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 1.分治法 基…

Spark常问面试题---项目总结

一、数据清洗&#xff0c;你都清洗什么&#xff1f;或者说 ETL 你是怎么做的&#xff1f; 我在这个项目主要清洗的式日志数据&#xff0c;日志数据传过来的json格式 去除掉无用的字段&#xff0c;过滤掉json格式不正确的脏数据 过滤清洗掉日志中缺少关键字段的数据&#xff…

基于智能语音交互的智能呼叫中心工作机制

在智能化和信息化不断进步的现代&#xff0c;智能呼叫中心为客户提供高质量、高效率的服务体验&#xff0c;提升众多品牌用户的满意度和忠诚度。作为实现智能呼叫中心的关键技术之一的智能语音交互技术&#xff0c;它通过集成自然语言处理&#xff08;NLP&#xff09;、语音识别…

Android Studio 右侧工具栏 Gradle 不显示 Task 列表

问题&#xff1a; android studio 4.2.1版本更新以后AS右侧工具栏Gradle Task列表不显示&#xff0c;这里需要手动去设置 解决办法&#xff1a; android studio 2024.2.1 Patch 2版本以前的版本设置&#xff1a;依次打开 File -> Settings -> Experimental 选项&#x…

SpringBoot集成Kafka和avro和Schema注册表

Schema注册表 为了提升kafka的性能&#xff0c;减少网络传输和存储的数据大小&#xff0c;可以把数据的schema部分单独存储到外部的schema注册表中&#xff0c;整体架构如下图所示&#xff1a; 1&#xff09;把所有数据需要用到的 schema 保存在注册表里&#xff0c;然后在记…

http(请求方法,状态码,Cookie与)

目录 1.http中常见的Header(KV结构) 2.http请求方法 2.1 请求方法 2.2 telnet 2.3 网页根目录 2.3.1 概念 2.3.2 构建一个首页 2.4 GET与POST方法 2.4.1 提交参数 2.4.2 GET与POST提交参数对比 2.4.3 GET和POST对比 3.状态码 3.1 状态码分类 3.2 3XXX状态码 3.2 …

十,[极客大挑战 2019]Secret File1

点击进入靶场 查看源代码 有个显眼的紫色文件夹&#xff0c;点击 点击secret看看 既然这样&#xff0c;那就回去查看源代码吧 好像没什么用 抓个包 得到一个文件名 404 如果包含"../"、"tp"、"input"或"data"&#xff0c;则输出"…

pytest自定义命令行参数

实际使用场景&#xff1a;pytest运行用例的时候&#xff0c;启动mitmdump进程试试抓包&#xff0c;pytest命令行启动的时候&#xff0c;传入mitmdump需要的参数&#xff08;1&#xff09;抓包生成的文件地址 &#xff08;2&#xff09;mitm的proxy设置 # 在pytest的固定文件中…

Unity AssetBundles(AB包)

目录 前言 AB包是什么 AB包有什么作用 1.相对Resources下的资源AB包更好管理资源 2.减小包体大小 3.热更新 官方提供的打包工具:Asset Bundle Browser AB包资源加载 AB包资源管理模块代码 前言 在现代游戏开发中&#xff0c;资源管理是一项至关重要的任务。随着游戏内容…

(一)Linux下安装NVIDIA驱动(操作记录)

目录 一、查看CUDA版本 1.输入nvidia-smi&#xff0c;查看驱动支持的最大CUDA版本&#xff0c;这里是11.6 2.输入nvcc --version&#xff0c;查看当前安装的CUDA版本&#xff0c;这里是11.3 二、卸载旧的NVIDIA驱动 1.卸载原有驱动 2.禁用nouveau&#xff08;必须&#x…

用Python做数据分析环境搭建及工具使用(Jupyter)

目录 一、Anaconda下载、安装 二、Jupyter 打开 三、Jupyter 常用快捷键 3.1 创建控制台 3.2 命令行模式下的快捷键 3.3 运行模式下快捷键 3.4 代码模式和笔记模式 3.5 编写Python代码 一、Anaconda下载、安装 【最新最全】Anaconda安装python环境_anaconda配置python…

Ai编程cursor + sealos + devBox实现登录以及用户管理增删改查(十三)

一、什么是 Sealos&#xff1f; Sealos 是一款以 Kubernetes 为内核的云操作系统发行版。它以云原生的方式&#xff0c;抛弃了传统的云计算架构&#xff0c;转向以 Kubernetes 为云内核的新架构&#xff0c;使企业能够像使用个人电脑一样简单地使用云。 二、适用场景 业务运…

重学设计模式-工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)

在平常的学习和工作中&#xff0c;我们创建对象一般会直接用new&#xff0c;但是很多时候直接new会存在一些问题&#xff0c;而且直接new会让我们的代码变得非常繁杂&#xff0c;这时候就会巧妙的用到设计模式&#xff0c;平常我们通过力扣学习的算法可能并不会在我们工作中用到…

数据结构4——栈和队列

目录 1.栈 1.1.栈的概念及结构 1.2栈的实现 2.队列 2.1队列的概念及结构 2.2队列的实现 1.栈 1.1.栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一段称为栈顶&#xff0c;另一端称为…

家政小程序开发,打造便捷家政生活小程序

目前&#xff0c;随着社会人就老龄化和生活压力的加重&#xff0c;家政服务市场的需求正在不断上升&#xff0c;家政市场的规模也正在逐渐扩大&#xff0c;发展前景可观。 在市场快速发展的影响下&#xff0c;越来越多的企业开始进入到市场中&#xff0c;同时家政市场布局也发…

Spring Cloud Alibaba(六)

目录&#xff1a; 分布式链路追踪-SkyWalking为什么需要链路追踪什么是SkyWalkingSkyWalking核心概念什么是探针Java AgentJava探针日志监控实现之环境搭建Java探针日志监控实现之探针实现编写探针类TestAgent搭建 ElasticsearchSkyWalking服务环境搭建搭建微服务微服务接入Sky…

HTTP 探秘之旅:从入门到未来

文章目录 导言&#xff1a;目录&#xff1a;第一篇&#xff1a;HTTP&#xff0c;互联网的“快递员”第二篇&#xff1a;从点开网页到看到内容&#xff0c;HTTP 究竟做了什么&#xff1f;第三篇&#xff1a;HTTP 的烦恼与进化史第四篇&#xff1a;HTTP 的铠甲——HTTPS 的故事第…

万字长文解读深度学习——多模态模型BLIP2

&#x1f33a;历史文章列表&#x1f33a; 深度学习——优化算法、激活函数、归一化、正则化 深度学习——权重初始化、评估指标、梯度消失和梯度爆炸 深度学习——前向传播与反向传播、神经网络&#xff08;前馈神经网络与反馈神经网络&#xff09;、常见算法概要汇总 万字长…

qt QToolBox详解

1、概述 QToolBox是Qt框架中的一个控件&#xff0c;它提供了一个带标签页的容器&#xff0c;用户可以通过点击标签页标题来切换不同的页面。QToolBox类似于一个带有多页选项卡的控件&#xff0c;但每个“选项卡”都是一个完整的页面&#xff0c;而不仅仅是标签。这使得QToolBo…

如何把阿里云ECS里的文件下载到本地(免登录免配置)

如何把阿里云ECS里的文件下载到本地&#xff08;免登录免配置&#xff09; 作为一个阿里云ECS的用户&#xff0c;Up时长会遇到希望把ECS里的文件下载到自己的个人电脑&#xff0c;然后在自己的电脑里面查看&#xff0c;保存或者发送给别人。最近发现阿里云新上了一个功能&…