The string "PAYPALISHIRING"
is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
P A H N A P L S I I G Y I RAnd then read line by line:
"PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3)
should return
"PAHNAPLSIIGYIR"
.
思路:
题目是要把原本折线形的string转换成按行数读取的string。观察得到,每行出现的周期是2 * numRows - 2,首行和最后一行一个周期只出现一次,中间的行会出现两次,所以处在折线状态下的char也要考虑到。比如numRows是3的情况下,第一列的A是第二行,第二列的P也是第二行,他们处于一个重复周期中,两个char之间的index差是2,规律是2 * (numRows - 1 - i)。i代表行数,注意这里的数组下标是从0开始的,所以numRows要减去1。
public static String convert(String s, int numRows) {
if (numRows < 2)
return s;
StringBuilder res = new StringBuilder();
for (int i = 0; i < numRows; i++) {
// 每行的往返规律是(numRows - 2) * 2 + 2
for (int j = i; j < s.length(); j += 2 * numRows - 2) {
res.append(s.charAt(j));
// 如果不是最后一行和第一行
if (i > 0 && i < numRows - 1) {
if (j + 2 * (numRows - 1 - i) < s.length()) {
res.append(s.charAt(j + 2 * (numRows - 1 - i)));
}
}
}
}
return res.toString();
}
discuss区两个几乎百分之100的算法我都试了一下,phyon改成java只能百分之11,另一个c++的现在在c++区也只有百分之45了,残念~