6.Z字形变换




6. Z 字形变换
题意
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排
列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
APLSIIG
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 LS IG
YA HR
P I
示例 3:
• 输入:s = “A”, numRows = 1
• 输出:“A”
难度
中等
分析
看到这道题的描述,需要先搞清楚,如何把一个字符串按照指定的行数进行 Z 字形排列,
这是这道题的关键所在。
当然了,严格上来说,是倒着的 Z 字,题目应该叫 N 字形()更确切一点。 ?
? ) 更 确 切 一 点 。
哦,N 字形也不确切,确切的说应该是这样 |/|,这样有什么规律呢?
• 先向下走,走到底
• 触底向上,往上走
• 触顶再向下,如此往复
假设有一个字符串 沉默王二是傻调,numRows = 3,我们来通过图示的方式盘一盘。
三行我们就初始化三个 StringBuilder 数组,用来存放每一行的字符,然后我们就开始按
照上面的规律来进行字符的存放。
006.Z%E5%AD%97%E5%BD%A2%E5%8F%98%E6%8D%A2-20231226144320.png
第一行放入“沉”,第二行放入“默”,第三行放入“王”。
006.Z%E5%AD%97%E5%BD%A2%E5%8F%98%E6%8D%A2-20231226144458.png
触底之后需要往上走,所以第二行放入“二”,第一行放入“是”。
006.Z%E5%AD%97%E5%BD%A2%E5%8F%98%E6%8D%A2-20231226144835.png
又触顶了,需要往下走,所以第二行放入“傻”,第三行放入“调”。
006.Z%E5%AD%97%E5%BD%A2%E5%8F%98%E6%8D%A2-20231226145648.png
由此,大家应该有解题的思路吧,我们来看看代码是怎么实现的。
class Solution {
public String convert(String s, int numRows) {
// 特殊情况处理:单行或字符串长度小于行数时不需要转换
if (numRows == 1 || numRows >= s.length()) {
return s;
}
// 初始化 StringBuilder 数组,每个 StringBuilder 对象代表一行
StringBuilder[] rows = new StringBuilder[numRows];
for (int i = 0; i < numRows; i++) {
rows[i] = new StringBuilder();
}
int curRow = 0; // 当前行
boolean down = false; // 方向标志,用于控制行的移动
// 遍历字符串中的每个字符
for (char c : s.toCharArray()) {
// 将字符添加到当前行
rows[curRow].append(c);
// 当达到 Zigzag 的顶部或底部时,改变方向
if (curRow == 0 || curRow == numRows - 1) {
down = !down;
}
// 根据方向更新当前行
curRow += down ? 1 : -1;
}
// 合并所有行,构建最终的字符串
StringBuilder result = new StringBuilder();
for (StringBuilder row : rows) {
result.append(row);
}
return result.toString();
}
}
①、单行,或者字符串长度小于行数时,不需要转换,直接返回原字符串即可。
②、初始化 StringBuilder 数组,每个 StringBuilder 对象代表一行。
③、遍历字符串中的每个字符,将字符添加到当前行。当触底或者触顶的时候,改变方
向。
④、合并所有行,构建最终的字符串。
非常好理解,时间复杂度也很理想,为 O(n)。
006.Z%E5%AD%97%E5%BD%A2%E5%8F%98%E6%8D%A2-20231226150633.png
总结
这道题的关键在于如何把一个字符串按照指定的行数进行 Z 字形排列,可以在纸上画一
画,就很容易想到题解中给出的方法,找规律就对了。
这道题涉及到的知识点有:
• 字符串:深入解读字符串源码
• 数组:掌握数组
• for 循环:for 循环
• StringBuilder:掌握 StringBuilder
知识点都很简单,大家可以通过《二哥的 Java 进阶之路》去学习。唯一的巧劲就在于 flag
的运用,触底向上,触顶向下。
力扣链接:https://leetcode.cn/problems/zigzag-conversion/