Title Description:
A given string is arranged in zigzag from top to bottom, left to right, according to the given number of lines.
For example, when the input string is "leetcodeiishing" and the number of lines is 3, the arrangement is as follows:
L C I R E T O E S I I G E D H N
After that, your output needs to be read line by line from left to right to produce a new string, such as "lcireteoesiigedhn".
Please implement this function to transform a string into a specified number of lines:
string convert(string s, int numRows);
Example 1:
Input: S = "leetcodeiishing", NumRows = 3 Output: "lcireteoesiigedhn"
Example 2:
input: s = "LEETCODEISHIRING", numRows = 4 //Output: "ldreoeieiechintsg" //Interpretation: L D R E O E I I E C I H N T S G
Solution 1: sort by row
Core idea: by iterating the string from left to right, we can judge the position of the current character.
Algorithm implementation: first of all, you need to get the number of StringBuilder to be created, that is, how many lines are needed for Z-transformation. Then iterate through the string from left to right, adding each character to the appropriate line. Two variables, curRow and goingDown, are used for state tracking. When moving to the first or last line, the zigzag direction is converted.
The code is as follows:
class Solution { public String convert(String s, int numRows) { //If numsRows is 1, return s directly if(numRows == 1){ return s; } List<StringBuilder> rows = new ArrayList<>(); //Create StringBuilder, equivalent to the line number required to get the Z-shape for(int i = 0; i < Math.min(numRows, s.length()); i++){ rows.add(new StringBuilder()); } //Mark current line number int curRow = 0; //Record current line position status boolean goingDown = false; for(char c : s.toCharArray()){ //Splicing rows.get(curRow).append(c); //If the current line is the first or last line, change the status bit if(curRow == 0 || curRow == numRows-1){ goingDown = !goingDown; } curRow += goingDown ? 1 : -1; } //Get the Z-converted string StringBuilder ret = new StringBuilder(); for(StringBuilder row: rows){ ret.append(row); } return ret.toString(); } }
Method 2: access by line
Core idea: access the string in the same order as reading the zigzag pattern line by line.
Algorithm implementation: first access all characters in line 0, then access the first line, and so on
Law:
For all integers k:
The character in line 0 is in the position with the subscript k*(2*numRows-2);
The character in the last line is at the position with the subscript k*(2*numRows-2)+numRows-1
The characters in line i are located at k*(2*numRows-2)+i and (k+1)*(2*numRows-2)-i
Code implementation:
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(); } }