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 s, int numRows);
Example 1:
Input: s = "PAYPALISHIRING", numRows = 3 Output: "PAHNAPLSIIGYIR"
Example 2:
Input: s = "PAYPALISHIRING", numRows = 4 Output: "PINALSIGYAHRPI" Explanation: P I N A L S I G Y A H R P I
Example 3:
Input: s = "A", numRows = 1 Output: "A"
Constraints:
1 <= s.length <= 1000
s
consists of English letters (lower-case and upper-case),','
and'.'
.1 <= numRows <= 1000
Z字形变换。
题意是给一个正常的字符串,和一个参数numRows,请以Z字形表示出来。例子,
Example:
Input: s = "PAYPALISHIRING", numRows = 4 Output: "PINALSIGYAHRPI" Explanation: P I N A L S I G Y A H R P I
如例子所示,input字符串被展示成了4行。这个题没有什么算法,我这里介绍一个我看到的非常好的YouTube视频。我会结合这个图讲思路,图也来自于视频。
思路是用Java创建一个StringBuilder array,里面加入numRows个StringBuilder,然后遍历input。首先是从上往下竖直的部分,因为已经知道了行数所以遍历的时候用 sb[i].append(c[index++]); 写入字符,i是在track行数,index是在track字符串。当i == numRows的时候,会跳出这个循环;
接下来是从左下到右上的部分,因为P已经在第一个for循环写进去了所以接下来要写A和L。如果所示,斜向上的元素始于sb[numRows - 2](原因在于sb[numRows - 1]是最下面一行),止于sb[1](sb[0]是第一行),遍历依然是用 sb[i].append(c[index++]); 写入字符。写入所有字符之后,将StringBuilder array里面所有的StringBuilder append在一起,再convert成string输出。
时间O(n)
空间O(n) - StringBuilder
1 class Solution { 2 public String convert(String s, int numRows) { 3 char[] c = s.toCharArray(); 4 int len = c.length; 5 StringBuilder[] sb = new StringBuilder[numRows]; 6 for (int i = 0; i < sb.length; i++) { 7 sb[i] = new StringBuilder(); 8 } 9 10 int index = 0; 11 while (index < len) { 12 for (int i = 0; i < numRows && index < len; i++) { 13 sb[i].append(c[index++]); 14 } 15 for (int i = numRows - 2; i >= 1 && index < len; i--) { 16 sb[i].append(c[index++]); 17 } 18 } 19 20 for (int i = 1; i < sb.length; i++) { 21 sb[0].append(sb[i]); 22 } 23 return sb[0].toString(); 24 } 25 }