题目
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = “LEETCODEISHIRING”, numRows = 3
输出: “LCIRETOESIIGEDHN”
示例 2:
输入: s = “LEETCODEISHIRING”, numRows = 4
输出: “LDREOEIIECIHNTSG”
解释:
L D R
E O E I I
E C I H N
T S G
解法一(数学推理)
思路:每个独立的Z形状进行分组,然后计算得到每个分组成员的相对索引,根据排列规则翻译过来输出字符即可:从上到下翻译为按行遍历,从左到右翻译为按列遍历。
- 将每组成员看为一个竖钩的形状,最后一组可能存在不全在的情况,因此每次访问前都检测是否越界
- 第一行和最后一行仅有一个元素,中间行有两个元素,因此一个组的元素个数为: n u m R o w s ∗ 2 − 2 numRows * 2 - 2 numRows∗2−2
- 元素索引由组内索引加组索引:竖列中元素,其组内相对索引为行号 i i i,加上组的索引 j ∗ c o u n t j*count j∗count;勾列中元素,距离下一组元素开头的距离为 i i i,因此使用下一组元素索引减去行号
- 时间复杂度:O(n)
- 空间复杂度:O(n)
public class Solution {
public string Convert(string s, int numRows) {
if(numRows == 1)
{
//只有一行时,直接返回结果,防止下面除数为0
return s;
}
StringBuilder sb = new StringBuilder();