Z igzag conversion

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();
    }
}

 

Posted by Pro.Luv on Mon, 02 Dec 2019 05:51:44 -0800