首页 简历|笔试面试

6.Z字形变换

  • 25年9月4日 发布
  • 266.65KB 共7页
6.Z字形变换6.Z字形变换6.Z字形变换6.Z字形变换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/

开通会员 本次下载免费

所有资料全部免费下载! 推荐用户付费下载获取返佣积分! 积分可以兑换商品!
一键复制 下载文档 联系客服