在LeetCode的第六个算法问题中,要求给定行数numRows,将一个字符串转变为ZigZag字符串再逐行读出。
ZigZag字符串即由常规字符串通过Z字形排列形成。
举个例子,Mathematics在给定行数为4的情况下,其ZigZag字符串形式如下:
M a
a mt
t e i s
h c
而需要输出的是逐行读出的结果,即Maamtteishc
从实现的角度来说,比较容易想到的是使用一个二维数组以Z字形存储字符串的每一个字符,存储完之后再遍历该二维数组读出结果即可。
存储的过程从平面方向来说,Z字形存储是先向下存储,到底后再向右上方存储,到顶之后又向下存储,如此往复循环的过程。
因此在存储上可以通过二维数组的两个下标的变化来实现Z字形存储。
实现的方法如下:
public String getZigZag(String s,int numRows){
if(numRows==1)
return s;
StringBuilder sb = new StringBuilder();
char[][] matrix = new char[numRows][(s.length()+1)/2];
int m=0,n=0;
int mPlus = -1;
int nPlus = 0;
for(int i=0;i<numRows;i++){
for(int j=0;j<(s.length()+1)/2;j++){
matrix[i][j] = '\t';
}
}
for(int i=0;i<s.length();i++,m+=mPlus,n+=nPlus){
if(m==numRows-1){
mPlus = -mPlus;
nPlus = 1;
}
if(m==0){
mPlus = -mPlus;
nPlus = 0;
}
matrix[m][n] = s.charAt(i);
}
for(int i=0;i<numRows;i++){
for(int j=0;j<(s.length()+1)/2;j++){
if(matrix[i][j] != '\t'){
sb.append(matrix[i][j]);
}
}
}
return sb.toString();
}
除了上面这种方式之外,还可以通过创建numRows个StringBuilder来存储每一行字符。这种方式在实现上更加的简洁明了。实现方法如下:
public String getZigZag(String s,int numRows){
StringBuilder[] sbs = new StringBuilder[numRows];
for(int i=0;i<numRows;i++)
sbs[i] = new StringBuilder();
int i=0;
int m=0;
while(i<s.length()){
for(m=0;m<numRows&&i<s.length();m++)
sbs[m].append(s.charAt(i++));
for(m=numRows-2;m>0&&i<s.length();m--)
sbs[m].append(s.charAt(i++));
}
StringBuilder sb = new StringBuilder();
for(int j=0;j<numRows;j++){
sb.append(sbs[j].toString());
}
return sb.toString();
}