题目链接
思路:
找出Z字的规律。以每一个z字的“ | ” 和" / " 作为一组,进行分组,每组有 2 * numRows - 2 个字符。
例:“LEETCODEISHIRING"
行数为 3
L C I R L C E T O E S I I G 以 E T 为一组, O E 为一组。 E D H N E D
" | " 的部分大小为 numRows,“ / ”的部分大小为 2 * numRows - 2 - numRows = numRows - 2;
“ / ” 部分的初始间隔为 2 * numRows - 2 - 2,此后需要更新。
" | " 部分的顺序在原始字符串中为从前到后,“ / "部分的顺序在原始字符串中为从后到前
例如:
“LEETCODEISHIRING"
行数为 4
L D R E O E I I E C I H N T S G
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
L | E | E | T | C | O | D | E | I | S | H | I | R | I | N | G |
对于中间部分,先是 O I 再是 C H。
首行和最后一行不需要加中间部分,直接添加即可,中间部分从后往前遍历,其他部分从前往后遍历。
详细处理步骤,请看代码。
public String convert(String s, int numRows) {
if (s == null || s.length() < 2 || numRows < 2 || s.length() <= numRows) {
return s;
}
StringBuilder sb = new StringBuilder();
int index = 0;
int jump = numRows * 2 - 2;
int len = s.length();
int mid = numRows - 2; // 中间部分的字符数
int midJump = jump - 2; // 中间部分的跳转数
for (int i = 0; i < numRows; i++) {
index = i;
if (index == 0 || index == numRows - 1) {
for (;index < len; index = index + jump) {
sb.append(s.charAt(index));
}
} else {
for (;index < len; index = index + jump) {
sb.append(s.charAt(index));
if (mid > 0 && index + midJump < len) {
sb.append(s.charAt(index + midJump));
}
}
midJump -= 2; // 中间位置每次都是逆序添加,
// 故一次添加后,需要减2
// (由于index会加1,中间位置需要减1,里外里减2)
mid--; // 中间部分还剩几个字符
}
}
return sb.toString();
}