题目描述:
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"
Explanation:
P A H N
A P L S I I G
Y I R
Example 2:
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I
My Solution(19ms,38.4MB)
首先想到的办法,有点绕,用一个二维数组按照之字形储存起来,然后逐行逐列地去读取,然后拼接成一个字符串。
class Solution { public String convert(String s, int numRows) { if(numRows<2){return s;}//防止除数为零 int index = 0,row=numRows-2; //columns实际上是指二维数组列下表的最大值 int columns = s.length()/(2*numRows-2)*(numRows-1); int remainder = s.length()%(2*numRows-2); if(remainder>numRows){columns = remainder - numRows + columns;} String[][] zigzag = new String[numRows][columns+1]; //开始逐行填充数组 for(int j = 0;j<columns+1;j++){ if(j%(numRows-1)==0){//竖笔 for(int i = 0;i<numRows;i++){ if(index<s.length()){ zigzag[i][j] = s.substring(index,index+1);index++; row = numRows-2; } } }else{ if(index<s.length()){ zigzag[row][j] = s.substring(index,index+1);index++; row--; } } } //开始拼接结果字符串 String result = ""; for(int i =0 ; i<numRows ;i++){ for(int j=0;j<columns+1;j++){ if(zigzag[i][j]!=null){ result = result + zigzag[i][j]; } } } return result; } }
Visit By Row(3ms,36MB)
发现数字间的规律,直接逐行去读取(效率最高)
class Solution { public String convert(String s, int numRows) { if (numRows == 1) return s; StringBuilder ret = new StringBuilder(); int n = s.length(); int cycleLen = 2 * numRows - 2; //逐行去读取 for (int i = 0; i < numRows; i++) { for (int j = 0; j + i < n; j += cycleLen) { ret.append(s.charAt(j + i)); //排除第一行和最后一行,因为两竖笔之间没有数字 if (i != 0 && i != numRows - 1 && j + cycleLen - i < n) ret.append(s.charAt(j + cycleLen - i)); } } return ret.toString(); } }