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"
.
Subscribe to see which companies asked this question.
题目理解:将输入的字符串,字符顺序重排后输出,可以简单理解为将一维向量转换为了二维的矩阵,最后将二维矩阵又拼接成一维向量返回。
重排规则:zigzag,之字形扫描。
解决的大体思路:根据输入的之子宽度参数nRows,将text不同下标的字符散列到不同行的字符串中,最后按行重新拼接起来。为了方便追加字符,每一行使用的是StringBuilder result[nRows]。
eg:
0 | 8 | 16 | |||||||||
1 | 7 | 9 | 15 | 17 | |||||||
2 | 6 | 10 | 14 | 18 | |||||||
3 | 5 | 11 | 13 | 19 | |||||||
4 | 12 | 20 |
|
具体的将,再散列字符到不同行时,有两种思路可以考虑:
(1)根据输入的nRows,将text分组,在组内有相同位置的字符会被追加到同一行字符中。如上图所示,nRows=5,那么每组的长度为2*5-2=8;可以看到每8个字符都是一组相同的形状和散列位置排布。我们计算组内每个字符应当放入哪行字符串,同时完成向result[]散列的过程。注意到,在同一组内,字符放入result[]的行号会有增加和减小两个过程。在使用本思路精确计算式应当注意。
代码:
public class Solution {
public String convert(String s, int numRows) {
StringBuilder[] result=new StringBuilder[numRows];
char[] array=s.toCharArray();
for(int i=0;i<numRows;i++)result[i]=new StringBuilder(s.length());
//对每一个stringbulider初始化
int i=0,loc=0;
while(i<s.length()){
for(loc=0;loc<numRows && i<s.length();i+=1,loc+=1){
result[loc].append(array[i]);
}//由0开始的行号上升过程,同时字符串指示下标也要移动
for(loc=numRows-2;loc>0 && i<s.length();i+=1,loc-=1){
result[loc].append(array[i]);
}//由numRows-2开始的行号下降过程,同时字符串指示下标也要移动
}
for(i=1;i<numRows;i++){
result[0].append(result[i]);
}
return result[0].toString();
}
}
(2)注意到,在字符散列进result[]的行号会有增加和减小两个过程,利用边界值0和nRows-1,来改变待散列指示标记loc的移动方向,即可完成正确散列。值得注意的是,使用该思路需要留意nRows为1的情况,需要在代码的最开始做出特殊情况处理。
代码:
public class Solution {
public String convert(String s, int numRows) {
if(s.length()<=numRows||numRows==1)return s;
StringBuilder[] result=new StringBuilder[numRows];
char[] array=s.toCharArray();
int len=s.length();
for(int i=0;i<numRows;i++)result[i]=new StringBuilder(len);
int i=0,loc=0,step=1;
while(i<len){
result[loc].append(array[i]);
if(loc==numRows-1)step=-1; //下标减小
if(loc==0)step=1; //下标增加
loc+=step;
i+=1;
}
for(i=1;i<numRows;i++){
result[0].append(result[i]);
}
return result[0].toString();
}
}