Problem :
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:
就是把原始字符串按照“之”字型排列
例如:
原始字符串 : ABCDEFGHIJKLM
row = 3 : AEIMBDFHJLCGK
row = 4 : AGMBFHLCEIKDJ
这其实就是一个将原始字符串进行适当的转换变成另一种字符串。
观察转换字符串的特点是“之”字形的,但是读取文字的时候是一行一行来读取的,所以我们可以构建一个String数组,长度为numRows,用来存储每行字符串,最后的字符串则是str数组拼接起来即可。
由于字符串经常变化,为了节省内存,我们采用StringBuffer数组来存储相应的字符串。
考虑numRows == 1时,字符串只有一行,那么顺序读取即可,返回原始字符串。
考虑numRows == 2时,字符串有两行,字符每次跨行读取即可。
kaolvnumRows >= 3时,字符串有若干行,我们要建立一个StringBuffer数组来存储每行构成的字符串,最后将字符串拼接起来即可。算法的难点在于如何计算每个StringBuffer。
public class Solution{
public String convert(String s, int numRows){
if(numRows == 1){
return s;
}else if(numRows == 2) {
StringBuffer str = new StringBuffer("");
for (int i = 0; i < s.length(); i += 2) {
str.append(s.charAt(i));
}
for (int i = 1; i < s.length(); i += 2) {
str.append(s.charAt(i));
}
return new String(str);
}else{
int row = 0; //记录当前行
int col = 0; //一个检查点
int strCir = 0; //记录字符串s当前读取到的字符位置
StringBuffer str[] = new StringBuffer[numRows];
/*初始化StringBuffer数组,若不初始化,则会报出空指针异常*/
for(int i=0;i<str.length;i++){
str[i] = new StringBuffer("");
}
while(strCir<s.length()){
if(row == 0){
col = 1;
}
else if(row == numRows-1){
col = 0;
}
if(col == 1){
str[row].append(s.charAt(strCir));
row++;
strCir++;
}
if(col == 0){
str[row].append(s.charAt(strCir));
row--;
strCir++;
}
//连接str字符串
StringBuffer ans = new StringBuffer("");
for(int i=0;i<str.length;i++){
ans.append(str[i]);
}
return new String(ans);
}
}
}