将一个给定字符串 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);
示例:
输入:s = "PAYPALISHIRING", numRows = 4 输出:"PINALSIGYAHRPI" 解释: P I N A L S I G Y A H R P I
提示:
1 <= s.length <= 1000
s
由英文字母(小写和大写)、','
和'.'
组成1 <= numRows <= 1000
由于输出的逐行读取,考虑每一行使用一个StringBuilder进行存储。
遍历字符串,用row行号记录当前字符应该添加到哪一行。
row的更新规则:
- 引入指示变量now_forward标记当前排列方向向上还是向下。
- 每次添加一个字符串后更新row = row + now_forward。
- 当row到了第一行或者最后一行时,反转now_forward。
class Solution {
public String convert(String s, int numRows) {
if(numRows <=1){
return s;
}
StringBuilder[] sb = new StringBuilder[numRows];
for(int i = 0;i < numRows;i++){
sb[i] = new StringBuilder();
}
int row = 0;
int now_forward = 1;
char[] c = s.toCharArray();
for(int i = 0;i < c.length;i++){
sb[row].append(c[i]);
row += now_forward;
if(row == 0 || row == numRows-1){
now_forward = -now_forward;
}
}
StringBuilder result = new StringBuilder();
for(int i = 0;i < numRows;i++){
result.append(sb[i]);
}
return result.toString();
}
}
算法:
- 创建一个长度为
numRows
的StringBuilder
数组sb
,用于存储每行的字符。 - 初始化一个名为
row
的变量为0
,表示当前行。 - 初始化一个名为
now_forward
的变量为1
,表示当前方向(向下或向上)。 - 将字符串
s
转换为字符数组c
。 - 遍历字符数组
c
中的每个字符:- 将当前字符追加到
sb[row]
。 - 更新
row
:- 如果
row
等于0
或等于numRows-1
,则将now_forward
取反。 - 将
row
加上now_forward
。
- 如果
- 将当前字符追加到
- 创建一个
StringBuilder
result
,用于存储最终结果。 - 遍历
sb
数组,将每行的字符追加到result
中。 - 返回
result
的字符串表示。
**时间复杂度:**O(n),其中 n 是字符串 s
的长度。
**空间复杂度:**O(n),因为 sb
数组和 result
StringBuilder
存储的字符总数与字符串 s
的长度相同。