题目描述
将一个给定字符串 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);
示例 1:
输入: s = "PAYPALISHIRING", numRows = 3
输出: "PAHNAPLSIIGYIR"
示例 2:
输入: s = "PAYPALISHIRING", numRows = 4
输出: "PINALSIGYAHRPI"
解释:
P I N
A L S I G
Y A H R
P I
示例 3:
输入: s = "A", numRows = 1
输出: "A"
提示:
1 <= s.length <= 1000
s
由英文字母(小写和大写)、','
和'.'
组成1 <= numRows <= 1000
解题思路
PAYPALISHIRING
P | A | Y | P | A | L | I | S | H | I | R | I | N | G |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
三行的情况:
0 4 8 12
1 3 5 7 9 11 13
2 6 10
四行的情况:
0 6 12
1 5 7 11 13
2 4 8 10
3 9
第 1 行的字符位于 k ( 2 * numRows - 2 ) 的位置。所对应的下标。 (0,6,12)
最后一行 ( numRows - 1 ) 的字符位于 k ( 2 * numRows - 2 ) + numRows - 1 的位置。(3,9)
第 0 行和最后一行之间第 i 行的字符位于 k ( 2 * numRows − 2 ) + i 以及 ( k + 1 )( 2 * numRows - 2 ) - i处。(1,5,7,11,13)
代码
/**
* @ProjectName: arithmetic
* @Description: Z 字形变换
* @Author: DuWL
* @Create: 2024-06-05 23:33
**/
public class Convert {
public static void main(String[] args) {
String s = "PAYPALISHIRING";
String str = convert(s, 4);
System.out.println(str);
}
public static String convert(String s, int numRows) {
if (numRows < 2) {
return s;
}
List<StringBuilder> rows = new ArrayList<>();
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 result = new StringBuilder();
rows.forEach(result::append);
return result.toString();
}
}