LeetCode 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);代码
class Solution {
public String convert(String s, int numRows) {
if(numRows < 2) return s;
List<StringBuilder> rows = new ArrayList<StringBuilder>();
for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());
int i = 0, flag = -1;
for(char c : s.toCharArray()) {
rows.get(i).append(c);
if(i == 0 || i == numRows -1) flag = - flag;
i += flag;
}
StringBuilder res = new StringBuilder();
for(StringBuilder row : rows) res.append(row);
return res.toString();
}
}
代码解析
初始处理:
if(numRows < 2) return s;:如果行数小于 2,直接返回原字符串,因为这种情况下没有必要进行 Z 字形排列。
初始化行列表:
List<StringBuilder> rows = new ArrayList<StringBuilder>();:创建一个列表rows,其中每个元素是一个StringBuilder对象,用于存储每行的字符。for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());:向rows列表中添加numRows个StringBuilder对象,每个对象代表一行。
遍历字符串并填充行列表:
int i = 0, flag = -1;:初始化行索引i和方向标志flag。i表示当前字符要填充的行,flag用于改变方向。for(char c : s.toCharArray()) {:遍历字符串s的每个字符c。rows.get(i).append(c);:将当前字符c添加到当前行i的StringBuilder中。if(i == 0 || i == numRows -1) flag = - flag;:当到达第一行或最后一行时,改变方向。i += flag;:根据方向flag更新行索引i。flag为 1 时向下移动,为 -1 时向上移动。
组合结果:
StringBuilder res = new StringBuilder();:创建一个StringBuilder对象res用于存储最终结果。for(StringBuilder row : rows) res.append(row);:遍历每个StringBuilder对象row,将其内容添加到res中。
返回结果:
return res.toString();:将结果res转换为字符串并返回。
示例
以 s = "PAYPALISHIRING" 和 numRows = 3 为例:
初始状态:
numRows = 3。
初始化行列表:
rows列表中包含 3 个StringBuilder对象,每个对象初始化为空。
填充行列表:
遍历字符串并填充行列表的过程如下:
P A H N A P L S I I G Y I R具体过程为:
- P (i=0)
- A (i=1)
- Y (i=2)
- P (i=1)
- A (i=0)
- L (i=1)
- I (i=2)
- S (i=1)
- H (i=0)
- I (i=1)
- R (i=2)
- I (i=1)
- N (i=0)
- G (i=1)
组合结果:
- 将
rows中每个StringBuilder对象的内容按顺序连接起来,得到结果PAHNAPLSIIGYIR。
- 将
结果
最终返回字符串 "PAHNAPLSIIGYIR"。