刷爆力扣之 Z 字形变换

简介: 刷爆力扣之 Z 字形变换

一 🏠 题目描述

6. Z 字形变换


将一个给定字符串 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 <=1000s 由英文字母(小写和大写)、',''.' 组成
1 <= numRows <=1000

二 🏠破题思路

2.1 🚀 关键信息

解决问题第一步,当然先提取题目字面上的关键信息 😎😎😎


示例 2:


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


将上面的解释转换,可得下图



可以发现 Z 字形排列实际上是有 下 (down)和 上 (rise)两种状态的 🌺🌺🌺


P     I    N    1713A   L S  I G   ——>      2681214Y A   H R    35911P     I     410

将解释转换为如上所示数字表示,经分析可知,{ 1,7 } ,{ 7,13 } ,{ 4,10 },任意一对它们的距离都是 6 ,即对于 Z 字形排列的上下端距离为 2 * numRows - 2 🌸🌸🌸


注:两次往返距离(2 * numRows)减去两端点的值(2)= 2 * numRows - 2



那么对于不是上下端的位置如何计算偏移量(Offsets)呢?


分析知对于任意位置都满足2 * currentNumRows - 2 ,即往返距离减去端点值 🌷🌷🌷


由上知 Z 字形排列有 下 (down)和 上 (rise)两种状态,使用字母 i 表示当前字母上面有几行字母


① 当 downStatus 时,currentNumRows = numRows - i


② 当 riseStatus 时,currentNumRows = i + 1



提取完题目中的关键信息后,直接进入第二阶段,思路整理 😃😃😃



2.2 🚀 思路整理

直接构造法


遍历字符串,按如关键信息所述编码即可(该题正确提取关键信息很重要)



整理完解题思路后,直接进入第三阶段,代码实现 😃😃😃



三 🏠 代码详解

3.1 🚀 代码实现

按照我们刚才的破题思路,直接代码走起来 👇👇👇👇


inline int getOffsets(int currentNumRows) {
  return 2 * currentNumRows -2; //对任意位置均满足往返距离减去端点值即为 Offsets
}
std::string convert(std::string s, int numRows) {
if (numRows ==1) return s; //numRows 为一行, 直接输出字符串
  int len = s.size(); //获取字符串长度
  std::string res(""); //初始化结果字符串
for (int i =0; i < numRows; ++i) { //遍历行数
  bool downStatus =true; //定义字符在 Z 字形排列中的状态
for (int j = i; j < len;) { //遍历字符串
    res += s[j]; //连接每行首字母
if (i ==0 || i == numRows -1) j +=2 * numRows -2; //对于上下端
else { //处理非上下端的两种状态, downOffsets & riseOffsets
if (downStatus) j += getOffsets(numRows - i), downStatus =false;
else j += getOffsets(i +1), downStatus =true;
    }
  }
  }
  return res; //返回结果字符串
}



3.2 🚀 细节解析

看完 👀👀👀 全注释版的代码实现后,相信看官大大对整体逻辑已经是大写的 OK 了 😃😃😃


那么我们挖掘上述实现的晦涩细节 😖😖😖 进行解析,直接开干,走起来 👇👇👇👇

if (downStatus) j += getOffsets(numRows - i), downStatus =false;

由题易知, Z 字形排列先往下,所以默认的 Status 为 downStatus 🐌🐌🐌

P     I    N    1713A   L S  I G   ——>      2681214Y A   H R    35911P     I     410

如上所示,例 2 —> 6 (当 2 偏移至 6 位置时),它状态为 riseStatus,故 downStatus 置为 false 🐳🐳🐳



四 🏠 心路历程

为方便各位看官大大了解博主真实刷题过程,我把当时状态纯纯真实还原,记录在心路历程这一小节,不感兴趣的小伙伴可以直接跳过哈


博主在第一阶段提取 🚀 关键信息没有问题,在第二阶段 🚀 思路整理没有问题,上述实现和题解博主原创


相关文章
|
6天前
|
算法
LeetCode算法题---最长回文子串、N 字形变换(四)
LeetCode算法题---最长回文子串、N 字形变换(四)
25 0
|
6天前
|
索引
leetcode代码记录(Z 字形变换
leetcode代码记录(Z 字形变换
13 1
|
6天前
|
Go
golang力扣leetcode 6.Z字形变换
golang力扣leetcode 6.Z字形变换
21 0
|
6天前
|
移动开发 算法 C#
Leetcode算法系列| 6. Z 字形变换
Leetcode算法系列| 6. Z 字形变换
|
10月前
|
算法 Python Perl
【力扣算法09】之 6. N 字形变换 python
【力扣算法09】之 6. N 字形变换 python
66 0
|
11月前
|
存储 测试技术 C++
力扣6-N 字形变换&力扣9- 回文数
力扣6-N 字形变换&力扣9- 回文数
51 0
|
11月前
|
算法 安全 Swift
LeetCode - #6 字符串“之”字形转换
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
11月前
leetcode:6.Z字形变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
38 0
|
6天前
|
算法 C++
【刷题】Leetcode 1609.奇偶树
这道题是我目前做过最难的题,虽然没有一遍做出来,但是参考大佬的代码,慢慢啃的感觉的真的很好。刷题继续!!!!!!
9 0
|
6天前
|
算法 索引
【刷题】滑动窗口精通 — Leetcode 30. 串联所有单词的子串 | Leetcode 76. 最小覆盖子串
经过这两道题目的书写,相信大家一定深刻认识到了滑动窗口的使用方法!!! 下面请大家继续刷题吧!!!
13 0