"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
Result: PQHNAPLSIIGYIR
If we think of the above as 2D matrix of letters, the key here is to figure out for each character of the string, what will be its row index and column index in the matrix? Once we have the 2D matrix, we can just go through it row by row to construct the output string.
In the above example, the number of row is 3. Then there will be 3-2=1 element between each multiple-element column. So if the string length is 4, 4/(3+(3-2))=1, there will be 1*(3-2+1) = 2 columns. If the string length is 5, 6, 7, there will be 1*(3-2+1) + 1 = 3 columns, if string length is 8, there will be 2*(3-2+1) = 4 columns.
Got the math?
And here is the code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public String convert(String s, int numRows) { | |
if(s==null || s.isEmpty() || s.length() == 1 || numRows <= 1) | |
return s; | |
int len = s.length(); | |
int numCols = getNumCols(len, numRows); | |
char[][] matrix = new char[numRows][numCols]; | |
for(int i=0; i<len; i++){ | |
matrix[getNumRows(i+1, numRows)-1][getNumCols(i+1, numRows)-1] = s.charAt(i); | |
} | |
StringBuilder sb = new StringBuilder(); | |
for(int r=0; r<numRows; r++){ | |
for(int c=0; c<numCols; c++){ | |
if(matrix[r][c]!='\0') | |
sb.append(matrix[r][c]); | |
} | |
} | |
return sb.toString(); | |
} | |
public int getNumRows(int len, int numRows){ | |
int t = len%(numRows-2+numRows); | |
if(t==0) | |
return 2; | |
else if(t>numRows) | |
return 2+numRows-2+numRows-t; | |
else | |
return t; | |
} | |
public int getNumCols(int len, int numRows){ | |
int t1 = len/(numRows-2+numRows); | |
int t2 = len%(numRows-2+numRows); | |
if(t2==0) | |
return t1*(numRows-1); | |
else if(t2>numRows) | |
return t1*(numRows-1) + t2 - numRows + 1; | |
else | |
return t1*(numRows-1) + 1; | |
} |