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”。
- 首先考虑特殊情况,当nRows=1时,也存在“ZigZag”模式,就是原字符串本身。
- 因为最后得到的字符串是按照行来读取的,所以利用一个StringBuffer,将每一行的数据一个个的append进去。
- 不难发现,第一行和最后一行,是特殊的,其差值是一个定值2*(nRows-1)。
- 除去第一行和最后一行,其余行数,根据上行/下行的方向,每次的间隔值是不同的,但是每两次的间隔值之和是一个定值:2*(nRows-1)。
- 用一个flag的标志位,记录上行/下行方向,每在内循环中读取一个字符之后,改变flag的值,跑完一次内循环之后(即读完一行),将标志位还原。
- 入参检查。
解题代码:
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 }
相关链接:
https://leetcode.com/problems/zigzag-conversion/
PS:如有不正确或提高效率的方法,欢迎留言,谢谢!
以上是关于No.006:ZigZag Conversion的主要内容,如果未能解决你的问题,请参考以下文章
#Leetcode# 6. ZigZag Conversion