第一感觉是用二维数组去存储每一个字符,找规律就好但是好像没找出来…
字符 | 索引 |
---|---|
P | 0 |
A | 1 |
Y | 2 |
P | 3 |
A | 4 |
L | 5 |
I | 6 |
S | 7 |
H | 8 |
I | 9 |
R | 10 |
I | 11 |
N | 12 |
G | 13 |
如果 numRows=4
第0行 -> P - I - N
对应索引 -> 0 - 6 -12
间距 -> 6 - 6
第1行 -> A - L - S - I - G
对应索引 -> 1 - 5 - 7 - 11 - 13
间距 -> 4 - 2 - 4 - 2
第2行 -> Y - A - H - R
对应索引 -> 2 - 4 - 8 - 10
间距 -> 2 - 4 - 2
第3行 -> P - I
对应索引 -> 3 - 9
间距 -> 6
不难看出,规律出在间距上,设 step = 2*numRows - 2,当numRows = 4 时,step = 6
并且每行的第一个元素所对应的索引都是行号
第一行和最后一行的元素之间的间距都是step
其余行的元素的间距都是 step-2*行数 与 2*行数 交换
public static String convert(String s, int numRows) {
if (numRows == 1) {
return s;
}
List<StringBuilder> rows = new ArrayList<>();
//在List集合中添加numRows个StringBuilder对象
for (int i = 0; i < numRows; i++) {
rows.add(new StringBuilder());
}
int step = 2 * numRows - 2;
for (int i = 0; i < numRows; i++) {
int index = i;
int add = i * 2;
if (i == 0) {
while (index < s.length()) {
rows.get(i).append(s.charAt(index));
index += step;
}
} else if (i == numRows - 1) {
while (index < s.length()) {
rows.get(i).append(s.charAt(index));
index += step;
}
} else {
while (index < s.length()) {
rows.get(i).append(s.charAt(index));
add = step - add;
index = index + add;
}
}
}
StringBuilder res = new StringBuilder();
for (StringBuilder row : rows) {
res.append(row);
}
return res.toString();
}
然后看到一位大佬的思路,由于字符都是在第零行和最后一行转向,放一个flag使其能够转向
public static String convert(String s, int numRows) {
if (numRows == 1) {
return s;
}
List<StringBuilder> rows = new ArrayList<>();
for (int i = 0; i < numRows; i++) {
rows.add(new StringBuilder());
}
int i = 0;
int flag = -1;
for (char c : s.toCharArray()) {
rows.get(i).append(c);
if (i == 0 || i == numRows - 1) {
flag = -flag;
}
i = i + flag;
}
StringBuilder res = new StringBuilder();
for (StringBuilder row : rows) {
res.append(row);
}
return res.toString();
}