LeetCode编程6--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格式排列,再读取每一行拼接成的字符串。

所谓的zigzag格式,有点类似锯齿波,为了找出规律,我们列举几组出来看看,字符串的内容替换成字符数组的下标,方便写程序,如下:

nRows=1

zigzag pattern: 0 1 2 3 4 5 6 7 ........ 

 

nRows=2

zigzag pattern:

0 2 4 6 8  ......

1 3 5 7 9 ......

 

nRows=3

zigzag pattern:

0          4           8              12

1    3    5    7    9      11    13   ......

2          6         10              14

 

nRows=4

zigzag pattern:

0                    6                            12

1            5      7                 11      13       ......

2     4             8       10               14

3                    9                           15

 

nRows=5

zigzag pattern:

0                           8                                                16

1                    7    9                                   15         17

2             6           10                    14                      18         ......

3      5                  11         13                                  19

4                           12                                               20

通过列出以上形式,可以总结出其中的规律:

1.nRows=1时是特殊情况,直接返回,以下下都是nRows>1的规律(默认行数是正整数)

2.无论nRows是多少,首行和尾行构成等差数列切差值一样,每一步差值step为(nRows-1)*2

3.当nRows为奇数时,中间那一行为等差数列,每一步差值step为nRows-1

4.除去首行尾行,以及奇数的中间行,剩下的行首位不完全对称,比如nRows=2时,第2行和第3行不完全对称,比如nRows=5时,第2行和第4行不完全对称

5.上一条规律中的所谓不完全对称是指:每一行不是等差数列,但是有两个固定的差值step1和step2,且对称行的差值对调,比如nRows=5时,第2行的step1=6,step2=2,对称的第4行step1=2,step2=6

最后写出跑通的JAVA代码如下:

public class ZigzagSolution {
public static void main(String args[]){
System.out.println(convert("skdf",2));
}

public static String convert(String s, int numRows) {

//检查字符串的值
if(s == null){
return null;
}
//numRows=1的情况,直接输出字符串
if(1 == numRows){
return s;
}
//拆分成字符串
char[] buf = s.toCharArray();
int len = buf.length;
//使用StringBuilder数组来储存结果,每一个StringBuilder接收一行的结果
StringBuilder[] builders = new StringBuilder[numRows];
for(int i=0; i < builders.length; i++){
builders[i] = new StringBuilder();
}

for(int i=0; i <= numRows/2; i++){//因为对称的关系,不用循环完全
//首尾构成等差数列的情况
if(0 == i){
//首部
int tmp = i;//tmp为每个对应字符的下标
int step = (numRows-1)*2;//步差
while(tmp < len){
builders[i].append(buf[tmp]);
tmp += step;
}
//尾部,首位不在同一个循环里,元素个数不一定一样
tmp = numRows-1-i;
int j = tmp;
while(tmp < len){
builders[j].append(buf[tmp]);
tmp += step;
}
}else if( (numRows%2)!=0 && i==(numRows/2)){//numRows为奇数,中间那行为等差数列
int tmp = i;
int step = numRows - 1;//步差
while(tmp < len){
builders[i].append(buf[tmp]);
tmp += step;
}
}else if(i < numRows/2){//其他对称的情况
int tmp =i;
int step1 = (numRows-2)*2 -(i-1)*2; //第一个步差
int step2 = 2*i; //第二个步差
boolean flag = true;
while(tmp < len){
builders[i].append(buf[tmp]);
if(flag){ //步差交替
tmp += step1;
flag = !flag;
}else{
tmp += step2;
flag = !flag;
}
}

tmp = numRows-1-i; //对称的另一行
int j = tmp;
flag = true;
while(tmp < len){
builders[j].append(buf[tmp]);
if(flag){
tmp += step2;
flag = !flag;
}else{
tmp += step1;
flag = !flag;
}
}
}else{
break;
}
}

String result = "";
for(int i=0; i < numRows; i++){
result += builders[i].toString();
}

return result;
}
}


你可能感兴趣的:(笔试题解)