首页 > 代码库 > ZigZag Conversion

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)

 

这题意说的完全不明确啊……看了网上说的才大概明白,题目中的zigzag模式大概是这样的吧:

0      4      8

1  3  5  7  9

2      6      10

也就是字符按如下图所示的方向填充:

可以发现,第0行包含了原字符串中下标为0,4,8……的字符,第1行包含1,5,9……的字符和3,7……的字符,以此类推。最后一行包含了2,6,10……。这是3阶的情况,下面列举四阶的情况:

0             6                12

1        5   7          11   13

2   4        8    10         14

3             9

同样,第0行包含了原字符串中下标为0,6,12……的字符,第1行包含1,7,13……的字符和5,11,17……的字符,以此类推。最后一行包含了3,9,15……。

经过分析,归纳出第i行包含的原字符串中字符所在的位置(n为上面所提到的阶数,s为原字符串):

case i==0:2k*(n-1)。(k取值从0开始到2k*(n-1)<s.length)

case i==n-1:(2k+1)*(n-1)。(k取值从0开始到(2k+1)*(n-1)<s.length)

case 其它:i+(n-1)*2k和-i+(n-1)*(2k+1)。

其中前两个case是第三个case的特殊情况,因为重复所以每次只取一个值

定义index1=index1 = i + (n - 1) * 2 * 用(index1 - index2) % (2 * (n - 1)) != 0来判断是不是第0行。

 

 1 public String convert(String s, int nRows) {
 2         String re = "";
 3         if (nRows == 1) {
 4             return s;
 5         }
 6         for (int i = 0; i < nRows; i++) {
 7             for (int k = 0; (i + (nRows - 1) * 2 * k) < s.length(); k++) {
 8                 int index1 = i + (nRows - 1) * 2 * k;
 9                 int index2 = -i + (nRows - 1) * 2 * (k + 1);
10                 re += String.valueOf(s.charAt(index1));
11                 if (index2 < s.length()
12                         && (index1 - index2) % (2 * (nRows - 1)) != 0) {
13                     re += String.valueOf(s.charAt(-i + (nRows - 1) * 2
14                             * (k + 1)));
15                 }
16             }
17         }
18         return re;
19     }

 

因为算法中原字符串每个字符只读取一次,因此时间复杂度为O(n)

 

结果: