模拟算法(3)_Z字形变换

news2024/11/26 19:47:47

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

模拟算法(3)_Z字形变换

收录于专栏【经典算法练习】
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 题目链接 :

2. 题目描述 :

3. 解法(模拟) :

   解法一(模拟 + 暴力):

    题目分析 :

    算法思路 :

    示例展示: 

    代码展示 :

    结果分析 :

   解法二(模拟 + 规律) : 

算法思路:

代码展示:

结果分析:

 


1. 题目链接 :

OJ链接 : Z字形变换

2. 题目描述 :

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

示例 2:

输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:

输入:s = "A", numRows = 1
输出:"A"

提示:

  • 1 <= s.length <= 1000
  • s 由英文字母(小写和大写)、',' 和 '.' 组成
  • 1 <= numRows <= 1000

3. 解法(模拟) :

   解法一(模拟 + 暴力):

    题目分析 :

假如题目给我们这样的字符串s : a. b. c. d. e. f. g. h. i. j. k. l. m. n numRows = 4

从上往下进行Z字形排列,然后从左往右逐行读取,产生出一个新的字符串: agmbfhlnceikdj

如下图所示: 

    算法思路 :

1. 输入判断:

首先,算法检查 numRows 是否小于等于 1 或大于等于字符串 s 的长度。如果是,则直接返回原字符串 s,因为在这些情况下,不需要进行任何转换。
2. 初始化:

创建一个字符串向量 rows 来存储每一行的内容。这个向量的大小是 min(numRows, (int)s.size()),以防字符串长度小于行数。
curRow 用于跟踪当前字符应该放入的行,初始值为 0。
goingDown 是一个布尔值,用于指示当前的遍历方向(向下或向上)。
3. 遍历字符串:

使用一个循环遍历字符串 s 中的每个字符。
将当前字符 ch 添加到对应的行 rows[curRow]。
判断是否到达了第一行(curRow == 0)或最后一行(curRow == numRows - 1)。如果到达了这些边界,就反转方向,即将 goingDown 的值取反。
根据当前方向更新 curRow 的值。如果 goingDown 为 true,则 curRow 加 1;否则减 1。
4. 组合结果:

最后,创建一个字符串 ret,将 rows 向量中的所有行连接在一起,形成最终结果。

    示例展示: 

假设输入字符串 s = "PAYPALISHIRING",并且 numRows = 3,算法的执行步骤如下:

初始化:

rows = ["", "", ""](三个空字符串)
curRow = 0
goingDown = false

遍历字符:

添加 P → rows = ["P", "", ""], curRow = 1
添加 A → rows = ["P", "A", ""], curRow = 2
添加 Y → rows = ["P", "A", "Y"], curRow = 1
添加 P → rows = ["P", "AP", "Y"], curRow = 0
添加 A → rows = ["PA", "AP", "Y"], curRow = 1
添加 L → rows = ["PA", "AP", "YL"], curRow = 2
添加 I → rows = ["PA", "API", "YL"], curRow = 1
添加 S → rows = ["PA", "APIS", "YL"], curRow = 0
添加 H → rows = ["PAH", "APIS", "YL"], curRow = 1
添加 I → rows = ["PAH", "APISI", "YL"], curRow = 2
添加 R → rows = ["PAH", "APISIR", "YL"], curRow = 1
添加 I → rows = ["PAH", "APISIRI", "YL"], curRow = 0
添加 N → rows = ["PAHN", "APISIRI", "YL"], curRow = 1
添加 G → rows = ["PAHN", "APISIRIG", "YL"], curRow = 2

    代码展示 :

class Solution {
public:
    string convert(string s, int numRows) {
        //如果行数小于等于或大于等于字符串长度,直接返回原字符串
        if(numRows <= 1 || numRows >= s.size()) return s;
        //创建一个字符串向量来存储每一行
        vector<string> rows(min(numRows, (int)s.size()));
        int curRow = 0; //当前索引
        bool goingDown = false;//方向标志,false表示向上,true表示向下
        //遍历字符串中的每个字符
        for(char ch : s)
        {
            rows[curRow] += ch;//将字符添加到当前行

            //当到达第一行或最后一行时,改变方向
            if(curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;//切换方向
            //更新当前索引
            curRow += goingDown ? 1 : -1;
        }
        //组合所有行
        string ret;
        for(auto ch : rows)
            ret += ch;
        return ret;
    }
};

    结果分析 :

时间复杂度
该算法的时间复杂度是 O(n),其中 n 是输入字符串的长度,因为每个字符都会被遍历一次。
空间复杂度
空间复杂度是 O(n),用于存储结果行数和结果字符串。 

   解法二(模拟 + 规律) : 

算法思路:

 

不难发现,数据是以 2row - 2 为⼀个周期进⾏规律变换的。将所有数替换成用周期来表示的变量:
第⼀行的数是:0, 2row - 2, 4row - 4;
第⼆行的数是:1, (2row - 2) - 1, (2row - 2) + 1, (4row - 4) - 1, (4row - 4) + 1;
第三行的数是:2, (2row - 2) - 2, (2row - 2) + 2, (4row - 4) - 2, (4row - 4) + 2;
第四行的数是:3, (2row - 2) + 3, (4row - 4) + 3。
可以观察到,第⼀行、第四行为差为 2row - 2 的等差数列;第二行、第三行除了第⼀个数取值为行
数,每组下标为(2n - 1, 2n)的数围绕(2row - 2)的倍数左右取值。
以此规律,我们可以写出迭代算法。

再进一步抽象成序号:

 

代码展示:

class Solution {
public:
    string convert(string s, int numRows) {
        string ret;
        if(numRows <= 1 || numRows >= s.size()) return s;

        //求出公差
        int d = 2 * numRows - 2;
        //处理第一行
        for(int i = 0; i < s.size(); i += d)
            ret += s[i];
        //处理中间k行
        for(int i = 1; i < numRows - 1; i++)
            for(int j = i; j < s.size(); j += d)
            {
                ret += s[j];
                if(j + d - 2 * i < s.size()) ret += s[j + d - 2 * i]; 
            }
        //处理最后一行
        for(int i = numRows - 1; i < s.size(); i += d)
            ret += s[i];
        return ret;
    }
};

 

结果分析:

综合
时间复杂度 : O(n)
空间复杂度 : O(n)

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

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

相关文章

VGG原理与实战

VGG网络结构 这也更好的块状结构,256个卷积核 卷积就是我们的一个特征图啊往往都会缩小 &#xff0c;然后的话但它通道不会变.卷积一般是使用我们的通道C变大,磁化但是它的通道就是我们那个H和W一般都会变小.下采样的意思就是使分辨率变小 vgg—block内的卷积层都是同结构的意…

【杂谈二之Relay继电器】介绍Relay继电器的概念、原理、分类以及实例应用

一、Relay是什么 Relay就是一个电控制的开关 二、Relay的工作原理 宏观上看主要由两部分电路组成&#xff0c;左侧的电路是低电流电路&#xff0c;右侧是高电流电路 左侧是由线圈绕制成&#xff0c;当有电流通过时就会产生磁场&#xff0c;会对于电枢产生吸引&#xff0c;由于…

【cpp/c++ summary 工具】 vcpkg 包管理器

由于之前的Hunter 包管理器在Boost的构建中速度太慢&#xff0c;准备尝试一下vcpkg。 vcpkg是由microsoft开发的、适用于 Windows、Linux 和 MacOS 的 C 库管理器。 1. 安装 vcpkg&#xff1a; 普通安装 C:\windows\system32>git clone https://github.com/microsoft/vcp…

华为 HCIP-Datacom H12-821 题库 (32)

&#x1f423;博客最下方微信公众号回复题库,领取题库和教学资源 &#x1f424;诚挚欢迎IT交流有兴趣的公众号回复交流群 &#x1f998;公众号会持续更新网络小知识&#x1f63c; 1.当一个运行 MSTP 协议的交换设备端口收到一个配置BPDU 时&#xff0c;会与设备保存的全局配…

20241005给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Android12时使用iperf3测网速

20241005给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Android12时使用iperf3测网速 2024/10/5 14:06 对于荣品RD-RK3588-AHD开发板&#xff0c;eth1位置上的PCIE转RJ458的以太网卡是默认好用的&#xff01; PCIE TO RJ45&#xff1a;RTL8111HS 被识别成为eth0了。inet addr:192.…

华为OD机试 - 最大连续文件之和(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

1.资源《Arduino UNO R3 proteus 仿真工程》说明。

资源链接&#xff1a; Arduino UNO R3 proteus 仿真工程 1.文件明细&#xff1a; 2.文件内容说明 包含&#xff1a;proteus工程、原理图、仿真程序。 3.内容展示 4.简述 该文件为proteus工程&#xff0c;用于Arduino uno r3仿真。 因为软件自动运行&#xff0c;所以最小…

深度学习每周学习总结J1(ResNet-50算法实战与解析 - 鸟类识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结1. 设置GPU2. 导入数据及处理部分3. 划分数据集4. 模型构建部分5. 设置超参数&#xff1a;定义损失函数&#xff0c;学习率&a…

c++结构体嵌套

没有很听懂这个课 有点乱了、 // // Created by 徐昌真 on 2024/10/5. // #include <iostream> using namespace std; int main() {struct Point{ //定义一个叫做point的结构体double x, y;};struct Radius{Point pt; //嵌套point结构体在radius结构体里面 把他名字定…

网络威胁情报技术的进步

网络威胁形势不断演变&#xff0c;必然导致防御者和攻击者之间持续展开军备竞赛。幸运的是&#xff0c;网络威胁情报 (CTI) 技术的进步为安全专业人员提供了强大的工具&#xff0c;使他们能够保持领先地位。 本指南深入探讨了 CTI 的最新进展&#xff0c;让您了解这些技术如何…

设计模式之桥接模式(Bridge)

一、桥接模式介绍 桥接模式(bridge pattern) 的定义是&#xff1a;将抽象部分与它的实现部分分离&#xff0c;使它们都可以独立 地变化。 桥接模式用一种巧妙的方式处理多层继承存在的问题&#xff0c;用抽象关联来取代传统的多层继承&#xff0c; 将类之间的静态继承关系转变为…

【CKA】十四、监控pod的日志

14、监控pod的日志 1. 考题内容&#xff1a; 2. 答题思路&#xff1a; 查看名字是foobar的pod的日志&#xff0c;过滤出 unable-to-access-website&#xff0c;导入到文件中就可以&#xff0c;这道题还是挺简单的 3. 官网地址&#xff1a; https://kubernetes.io/zh-cn/doc…

dll动态库加载失败导致程序启动报错以及dll库加载失败的常见原因分析与总结

目录 1、问题说明 2、dll库的隐式加载与动态加载 2.1、dll库的隐式加载 2.2、dll库的显式加载 3、使用Process Explorer查看进程加载的dll库信息以及动态加载的dll库有没有加载成功 3.1、使用Process Explorer查看进程加载的dll库信息 3.2、使用Process Explorer查看动态…

警惕!脑出血前这8大预警信号,你不可不知!

在这个快节奏的时代&#xff0c;健康成为了我们最宝贵的财富之一。然而&#xff0c;突如其来的疾病往往让人措手不及&#xff0c;尤其是像脑出血这样的严重疾病&#xff0c;其发病急、进展快&#xff0c;若不及时识别并就医&#xff0c;后果不堪设想。今天&#xff0c;我们就来…

在登陆功能中添加Redis缓存

目录 基于Redis实现短信登录 实现流程图 实现代码 解决登录状态刷新问题 初始方案思路&#xff1a; 实现代码 发送验证码 登陆实现 如果是新用户则自动创建 运行测试 基于Redis实现短信登录 实现流程图 实现代码 Overridepublic Result login(LoginFormDTO loginForm…

影刀RPA:Excel内容填充指令

1.实战目标 本次主要介绍影刀RPA如何操作内容相关的填充与替换指令。主要包含以下 这些指令在数据处理方面有着重要的作用&#xff0c;可以对数据做运算&#xff0c;填充&#xff0c;替换&#xff0c;实现数据格式统一&#xff0c;便于最终的数据分析。在操作的过程中&#xf…

WordPress修改固定链接后301的重定向方法

网站改版实际上是很忌讳的&#xff0c;尤其是针对已被搜索引擎收录的网站&#xff0c;新站不用考虑这些问题&#xff0c;而已经收录的网站网页在不遵守搜索引擎规则的前提下&#xff0c;是会被降权&#xff0c;关键词排名下滑、流量IP会被剥夺、收录会减少 、业务成交量会急剧下…

(Linux驱动学习 - 6).Linux中断

一. Linux 中断 API 函数 1.中断号 每个中断都有一个中断号&#xff0c;通过中断号即可区分不同的中断&#xff0c;有的资料也把中断号叫做中 断线。在 Linux 内核中使用一个 int 变量表示中断号。 2.申请中断 - request_irq 函数原型&#xff1a; int request_irq(unsigne…

【ubuntu】APT、apt、apt-get介绍

目录 1.APT简介 2.常用apt指令 2.1安装 2.2更新列表 2.3更新已经安装的软件包 2.4搜索软件包 2.5显示软件包信息 2.6移除软件包 2.7清理无用的安装包 2.8清理无用的依赖项 3.apt和apt-get 3.1区别 3.2 总结 1.APT简介 APT的全称是advanced package …

Java反射、自定义注解Demo

本文主要尝试使用反射、自定义注解&#xff0c;实现简单的Demo&#xff0c;所有代码均可直接复制使用。&#xff08;反射和注解是Java框架不可或缺的一部分&#xff0c;我们应该熟练掌握这部分知识&#xff01;&#xff09; 本文的代码结构如下&#xff1a; 代码如下&#xff…