试题请参见: https://leetcode.com/problems/zigzag-conversion/
题目概述
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 R
And 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"
.
解题思路
解释一下什么叫ZigZag, 一开始误解了题意折腾了好久.
可能我们需要用更多的行数可以使这个问题变得更明朗一些:
0 8 H
1 7 A G I
2 6 B F J
3 5 C E K
4 D L
对于如上字符串的输入是0123456789ABC...L
, 输出是08H17AGI26B...
对于如上例子, 我的思路是把字符串3组, 其中(0 .. 7)为一组, (8.. G)为一组, (H.. L)为一组. 除最后一组外, 每组包含numRows * 2 - 2
个元素(其中numRows
!= 1)。
那么每组中每一个元素应该位于第几行呢? 我们以(0.. 7)这组数据为例:
对于(0 .. 4), 所在行号等于字符串的索引ind % (numRows * 2 - 2)
,
对于(5 .. 7), 所在行号等于numRows * 2 - 2 - rowNumber
, 其中rowNumber = ind % (numRows * 2 - 2)
. (你会发现这一组中的每一行索引值相加是定值, 1 + 7 == 2 + 6 == 3 + 5 == numRows * 2 - 2
)
源代码
public class Solution {
public String convert(String s, int numRows) {
StringBuilder[] rowStrings = new StringBuilder[numRows];
for ( int i = 0; i < numRows; ++ i ) {
rowStrings[i] = new StringBuilder();
}
for ( int i = 0; i < s.length(); ++ i ) {
char currentChar = s.charAt(i);
int rowNumber = numRows == 1 ? 0 : i % (numRows * 2 - 2);
if ( rowNumber < numRows ) {
rowStrings[rowNumber].append(currentChar);
} else {
rowStrings[numRows * 2 - 2 - rowNumber].append(currentChar);
}
}
StringBuilder zigZag = new StringBuilder();
for ( int i = 0; i < numRows; ++ i ) {
zigZag.append(rowStrings[i]);
}
return zigZag.toString();
}
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.convert("A", 1)); // A
System.out.println(s.convert("ABC", 2)); // ACB
System.out.println(s.convert("ABCD", 2)); // ACBD
System.out.println(s.convert("PAYPALISHIRING", 3)); // PAHNAPLSIIGYIR
}
}