题目
分析
这题我采用的思路是用二维数组按照“Z”字形保存排布结果,再用水平方向遍历的方式去读取非0的部分,生成新的字符串。
基本步骤如下:
1、处理特殊情况,即空字符串和行数为1的字符串。非特殊情况下就生成二维数组,下面介绍二维数组的行列坐标的计算方法。行数即numRows值。列数的部分可以拆分为几步,先求出重复部分的重复次数,(s.length()/(2numRows-2))(numRows-1),我以“向下,右上”为最小重复单元,如例一的“LEET”部分;residue部分是剩余部分,当剩余部分小于numRows时,占一列,若大于等于numRows,则由s.length()%(2*numRows-2)/numRows计算得到。
char[][] str;
if(numRows==1){
if(s.length()==0){
return "";
}else{
return s;
}
}else{
int residue=0;
if(s.length()%(2*numRows-2)<numRows){
residue=1;
}else{
residue=s.length()%(2*numRows-2)/numRows;
}
str=new char[numRows][(s.length()/(2*numRows-2))*(numRows-1)+residue+s.length()%(2*numRows-2)%numRows];
}
2、为二维数组赋值(模拟赋值的过程)。flag1和flag2是行列两个角标的运动标识,过程比较好理解,运动到端点就调整运动方向,边运动边赋值,直到字符串的值赋完。
int i=0;//行号
int j=0;//列号
boolean flag1=true;//行标识,向下
boolean flag2=false;//列标识,向右
int count=0;
while(count<s.length()){
str[i][j]=s.charAt(count++);
if(i!=numRows-1&&flag1==true&&flag2==false){
i++;
}else if(i==numRows-1&&flag1==true&&flag2==false){
flag1=false;
flag2=true;
i--;
j++;
}else if(i!=0&&flag1==false&&flag2==true){
i--;
j++;
}else if(i==0&&flag1==false&&flag2==true){
flag1=true;
flag2=false;
i++;
}
}
3、水平逐行读取非零部分。
String string="";
for(int m=0;m<numRows;m++){
for(int n=0;n<(s.length()/(2*numRows-2))*(numRows-1)+s.length()%(2*numRows-2)/numRows+s.length()%(2*numRows-2)%numRows;n++){
if(str[m][n]!=0){
string+=str[m][n];
}
}
}
return string;