【算法-数组3】螺旋数组(一入循环深似海啊!)

news2024/11/23 3:16:51

今天,带来数组相关算法的讲解。文中不足错漏之处望请斧正!

理论基础点这里


螺旋数组

1. 思路

这道题主要是模拟转圈过程,但是要处理的边界条件比较多,常见的问题就是每条边的处理都有自己的逻辑,那这就很难。如果不明确每条边该如何遍历,比如当n=5,上行填充5个元素,但是右列又只填充4个元素——每条边的区间不统一,就导致旋转起来很困难。即使第一圈转完了,第二圈也不知道如何向内走。

在二分搜索的时候,我们讲过循环不变量,这里也可以用上,来使循环变得清晰。

我们这里对每条边的处理,采用左闭右开的规则,即左闭右开的处理边界是循环不变量。
同时,我们对整个螺旋矩阵的生成拆分一下:

  • 螺旋矩阵 = 按顺时针顺序旋转的一圈一圈递增的数字
  • 每圈数字 = 上行(从左到右)的填充 + 右列(从上到下)的填充 + 下行(从右到左)的填充 + 左列(从下到上)的填充

在这里插入图片描述
如图中一样,将目标矩阵拆分,最终只需要重复最简单的“右上左下填充操作”就可以生成目标矩阵。

具体怎么走呢?

*我们表示元素的时候一般是nums[i][j],i表示行的位置,j表示列的位置,所以等会遍历某一行的时候,元素nums[i][j]的列(j)在变化,循环变量用j;遍历某一列的时候,元素nums[i][j]的行(i)在变化,循环变量用i。

startI代表行的起始位置,startJ代表列的起始位置,则

  • 上行(遍历行,元素的列在变化):j: [startJ -> n-1);
  • 右列(遍历列,元素的行在变化):i: [startI -> n-1);
    在这里插入图片描述
    图中:
  • startI = 0
  • startJ = 0
  • j: [startJ, n-1)
  • i: [startI, n-1)

  • 下行(遍历行,元素的列在变化):j: [j -> startJ)
    • 由于向右走完,j已经为n-1,所以可以直接从j开始
  • 左列(遍历列,元素的行在变化):i: [i -> startI)
    • 由于向下走完,i已经为n-1,所以可以直接从i开始

在这里插入图片描述
图中:

  • startI = 0
  • startJ = 0
  • i= n-1
  • j= n-1
  • j: [n-1, startJ)
  • i: [n-1, startI)

最外一圈走完了,那怎么往里面走呢?

其实只需要稍稍改动:走完一圈,要转的圈就缩小了,即下一圈的行是[startJ+1, n-2),列同理。

左区间很简单,边转圈边增加startIstartJ,那右区间呢?不如我们直接默认给一个值为 n-1 的eleNum变量, 表示每次要填充的元素个数.

那我们转几圈呢?

n/2圈。因为每次转弯一圈,都是向最左列最右列、最上行最下行放置了元素。

那如果n是奇数呢?

就像我们图中画的一样,最后会剩下一个,我们在结尾特殊处理即可。

2. 参考代码

class Solution {
public:
    // 循环进行右下左上的填充操作
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> matrix(n, vector<int>(n, 0));

        // 关于行列:
        // 1. 遍历行, 列属性变化 -- j移动
        // 2. 遍历列, 行属性变化 -- i移动
        int startI = 0; // i起始位置
        int startJ = 0; // j起始位置
        int eleNum = n - 1; // 每次要填充的元素个数
        int loopNum = n / 2; // 循环次数(奇数需要单独处理最后一个元素)
        int val = 1; // 要填充的值

        while (loopNum--) {
            int i = startI; // 某元素的行属性
            int j = startJ; // 某元素的列属性

            // 从左到右遍历行(列属性变化 -- j移动)
            for (j = startJ; j < eleNum; ++j) matrix[i][j] = val++;

            // 从上到下遍历列(行属性变化 -- i移动)
            for (i = startI; i < eleNum; ++i) matrix[i][j] = val++;

            // 从右到左遍历行(列属性变化 -- j移动)
            for (; j > startJ; --j) matrix[i][j] = val++;

            // 从下到上遍历列(行属性变化 -- i移动)
            for (; i > startI; --i) matrix[i][j] = val++;

            // 每次循环后, 需要填充的区间左右同时向中间缩一位
            // 行: [startJ, eleNum) --> [startJ+1, eleNum-1)
            // 列: [startI, eleNum) --> [startI+1, eleNum-1)
            ++startI;
            ++startJ;
            --eleNum; 
        }

        //  当 n 为奇数, 矩形中间会留下一个没处理的
        if (n % 2 != 0) matrix[n / 2][n / 2] = val;

        return matrix;
    }
};

今天的分享就到这里了,感谢您能看到这里。

这里是培根的blog,期待与你共同进步!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于正负序双dq旋转坐标系锁相环 DDSRF-PLL模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; DDSRF-PLL则是通过构建数学解耦网络来消除&#xff12;倍电网频率的交流耦合分量 。由于DDSRF-PLL是在解耦多同步坐标系锁相环的基础上得到的&#xff0c;因此&#xff0c;需要研究解耦多同步坐标系锁相环的组…

高速串行总线—Rapid IO

SRIO简介 Rapid IO 是一种高性能、 低引脚数、 基于数据包交换的互连体系结构&#xff0c;是为满足和未来高性能嵌入式系统需求而设计的一种开放式互连技术标准。RapidIO主要应用于嵌入式系统内部互连&#xff0c;支持芯片到芯片、板到板间的通讯&#xff0c;可作为嵌入式设备的…

第26期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

Vue-router 路由的基本使用

Vue-router是一个Vue的插件库&#xff0c;专门用于实现SPA应用&#xff0c;也就是整个应用是一个完整的页面&#xff0c;点击页面上的导航不会跳转和刷新页面。 一、安装Vue-router npm i vue-router // Vue3安装4版本 npm i vue-router3 // Vue2安装3版本 二、引入…

什么是数据可视化,为什么数据可视化很重要?

数据可视化是数据的图形表示&#xff0c;可以帮助人们更轻松地理解和解释复杂的信息。它涉及创建数据的视觉表示&#xff0c;例如图表、图形、地图和其他视觉元素&#xff0c;以传达数据中的见解、模式和趋势。数据可视化是将原始数据转化为可操作知识的关键工具。 以下是数据…

CSS 背景、文本、字体

CSS背景&#xff1a; CSS背景属性用于定义HTML元素的背景。CSS属性定义背景效果&#xff1a;background-color&#xff1b;background-image&#xff1b;background-repeat&#xff1b;background-attachment&#xff1b;background-position。 background-color属性定义元素…

swift语言用哪种库适合做爬虫?

因为Swift语言并没有在语言层面上支持正则表达式&#xff0c;这对于爬虫来说是一个很大的缺陷。不过&#xff0c;Swift语言可以通过调用其他语言的库来实现爬虫功能&#xff0c;比如可以使用Python的BeautifulSoup库或者JavaScript的Cheerio库来解析HTML页面。但是相比于Python…

【Proteus仿真】【51单片机】汽车尾灯控制设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用按键、LED模块等。 主要功能&#xff1a; 系统运行后&#xff0c;系统运行后&#xff0c;系统开始运行&#xff0c;K1键控制左转向灯&#xff1b;…

第12章 PyTorch图像分割代码框架-2

模型模块 本书的第5-9章重点介绍了各种2D和3D的语义分割和实例分割网络模型&#xff0c;所以在模型模块中&#xff0c;我们需要做的事情就是将要实验的分割网络写在该目录下。有时候我们可能想尝试不同的分割网络结构&#xff0c;所以在该目录下可以存在多个想要实验的网络模型…

JVM虚拟机:垃圾回收器之Parallel Scavenge

本文重点 在前面的课程中,我们学习了新生代的串行化垃圾回收器Serial,本文我们将学习新生代的另外一个垃圾回收器Parallel Scavenge(PS),PS是一个并行化的垃圾回收器,它使用复制算法来清理新生代的垃圾。 运行方式 如上所示,当进行垃圾回收的时候,它会暂停工作线程,而…

第二章: 创建第一个Spring Boot 应用

第二章: 创建第一个Spring Boot 应用 前言 本章重点知识:构建你的第一个Spring Boot应用:以一个简单的例子来引导你进入Spring Boot的开发,包括如何使用Spring Initializr来创建项目,以及如何使用Maven或Gradle构建和运行项目等 IntelliJ IDEA 开发工具中安装 Spring Init…

网络原理---网络初识

文章目录 网络发展史独立模式网络互连局域网LAN广域网WAN 网络通信基础IP地址端口号 认识协议什么是协议&#xff1f;协议分层为什么要分层&#xff1f;两种典型的分层方式&#xff1a;OSI七层TCP/IP五层 网络发展史 从我们出生以来&#xff0c;网络世界就已经纷繁错杂。我们虽…

简单CMake入门

CMake可以生成不同平台下的Makefile&#xff0c;有了CMake不用再写复杂的Makefile 视频教程&#xff1a;CMake 6分钟入门&#xff0c;不用再写复杂的Makefile 先前知识 Makefile简单入门 Cmake特性 CMake是一个用于管理C/C项目的跨平台构建工具。 跨平台&#xff1a;CMake是…

CSS示例001:鼠标放div上,实现旋转、放大、移动等效果

GPT能够很好的应用到我们的代码开发中&#xff0c;能够提高开发速度。你可以利用其代码&#xff0c;做出一定的更改&#xff0c;然后实现效能。 css实战中&#xff0c;经常会看到这样的场景&#xff0c;鼠标放到一个图片或者一个div块状时候&#xff0c;会出现旋转、放大、移动…

webgoat-Insecure Deserialization不安全的序列化

A&#xff08;8&#xff09;不安全的反序列化 反序列化是将已序列化的数据还原回对象的过程。然而&#xff0c;如果反序列化是不安全的&#xff0c;那么恶意攻击者可以在序列化的数据中夹带恶意代码&#xff0c;从而在反序列化时执行这些代码。这种攻击被称为反序列化。 什么…

2023年中国大学生程序设计竞赛女生专场题解, K. RSP

Dashboard - 2023年中国大学生程序设计竞赛女生专场 - Codeforces K. RSP time limit per test1 second memory limit per test512 megabytes input standard input output standard output 小 A 和小 B 在玩一种叫做石头剪刀布的游戏。 这个游戏的规则很复杂&#xff0c…

Java8强大的新特性 —— “Stream API”

一、什么是Stream API&#xff1f; Java Stream API是Java 8中引入的一个重要功能&#xff0c;它允许开发者以声明性方式处理数据集合&#xff0c;使代码更加简洁、可读性更好&#xff0c;同时还提供了并行操作的能力&#xff0c;从而能够更有效地利用多核处理器。 Stream AP…

1.RestCloud部署安装

一、背景 项目使用StarRocks数仓,在网上找了一遍ETL工具,本来想用DataX ,但考虑到DataX的学习成本就没使用,最后找到了RestCloud,RestCloud提供了社区开源版本,提供图形化的操作界面,相对于DataX来说更容易上手。 二、环境准备 RestCloud依赖的环境如下: 1.安装准备…

『亚马逊云科技产品测评』活动征文|EC2云服务器一键部署wordpress博客

『亚马逊云科技产品测评』活动征文&#xff5c;EC2云服务器一键部署wordpress博客 授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技…

嵌入式面试常见问题(三)

1.linux下的proc文件夹是干什么的&#xff1f; 进程信息&#xff1a;/proc文件夹包含有关系统上运行的每个进程的信息。您可以在/proc中找到以进程ID&#xff08;PID&#xff09;为名称的子文件夹&#xff0c;每个子文件夹包含有关特定进程的信息&#xff0c;如状态、命令行参数…