No.006:ZigZag Conversion

Posted Gerrard_Feng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了No.006: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);

 

官方难度:

Easy

 

翻译:

现有字符串“PAYPALISHIRING”,写成n行“ZigZag”模式,结果为“PAHNAPLSIIGYIR”。

写出将一个字符串转译成“ZigZag”模式的代码。

 

额外例子:

字符串:“abcdefghijklmnopqrstuvwxyz”,nRows=5。

a       i       q       y

b     h j     p r     x z

c   g   k   o   s   w

d f     l n     t v

e       m       u

“ZigZag”字符串:“aiqybhjprxzcgkoswdflntvemu”。

 

  1. 首先考虑特殊情况,当nRows=1时,也存在“ZigZag”模式,就是原字符串本身。
  2. 因为最后得到的字符串是按照行来读取的,所以利用一个StringBuffer,将每一行的数据一个个的append进去。
  3. 不难发现,第一行和最后一行,是特殊的,其差值是一个定值2*(nRows-1)。
  4. 除去第一行和最后一行,其余行数,根据上行/下行的方向,每次的间隔值是不同的,但是每两次的间隔值之和是一个定值:2*(nRows-1)。
  5. 用一个flag的标志位,记录上行/下行方向,每在内循环中读取一个字符之后,改变flag的值,跑完一次内循环之后(即读完一行),将标志位还原。
  6. 入参检查。

 

解题代码:

 1 public static String convert(String s, int numRows) {
 2         if (s == null || numRows <= 0) {
 3             throw new IllegalArgumentException("Input error");
 4         }
 5         if (numRows == 1) {
 6             return s;
 7         }
 8         char[] array = s.toCharArray();
 9         StringBuffer buffer = new StringBuffer();
10         // 上行/下行标志位
11         int flag = 1;
12         // 间隔定值
13         int interval = 2 * (numRows - 1);
14         // 按行遍历
15         for (int i = 0; i < numRows; i++) {
16             // 每一行的数据
17             int j = 0;
18             while (i + j < array.length) {
19                 buffer.append(array[i + j]);
20                 // 第一行和最后一行
21                 if (i == 0 || i == numRows - 1) {
22                     j += interval;
23                 } else {
24                     if (flag == 1) {
25                         // 上行
26                         j += interval - 2 * i;
27                     } else {
28                         // 下行
29                         j += 2 * i;
30                     }
31                     // 改变下次的标志位
32                     flag *= -1;
33                 }
34             }
35             // 结束一行的遍历,标志位还原
36             flag = 1;
37         }
38         return buffer.toString();
39     }
convert

 

相关链接:

https://leetcode.com/problems/zigzag-conversion/

https://github.com/Gerrard-Feng/LeetCode/blob/master/LeetCode/src/com/gerrard/algorithm/easy/Q006.java

 

PS:如有不正确或提高效率的方法,欢迎留言,谢谢!

 

以上是关于No.006:ZigZag Conversion的主要内容,如果未能解决你的问题,请参考以下文章

ZigZag Conversion

#Leetcode# 6. ZigZag Conversion

ZigZag Conversion

leetcode6. ZigZag Conversion

学习(Swift)Leetcode 6. ZigZag Conversion

6. ZigZag Conversion (字符串的连接)