刷爆力扣之 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 字形变换(四)
41 0
|
5月前
|
算法 索引 Perl
力扣经典150题第二十二题:Z 字形变换
力扣经典150题第二十二题:Z 字形变换
40 1
|
5月前
|
存储 SQL 算法
LeetCode第六题:Z 字形变换 【6/1000 python】
LeetCode第六题:Z 字形变换 【6/1000 python】
|
6月前
|
索引
leetcode代码记录(Z 字形变换
leetcode代码记录(Z 字形变换
44 1
|
6月前
|
Go
golang力扣leetcode 6.Z字形变换
golang力扣leetcode 6.Z字形变换
38 0
|
6月前
|
移动开发 算法 C#
Leetcode算法系列| 6. Z 字形变换
Leetcode算法系列| 6. Z 字形变换
|
算法 Python Perl
【力扣算法09】之 6. N 字形变换 python
【力扣算法09】之 6. N 字形变换 python
94 0
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
55 6
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
113 2