Welcome to Subscribe On Youtube

Question

Formatted question description: https://leetcode.ca/all/6.html

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

Algorithm

Law: The first and last lines are added in the order of 2n-2. The position of the word diagonally across the line is the current column j+(2n-2)-2i (i is the index of the row).

Code

  • 
    public class ZigZag_Conversion {
    
        public class Solution {
            public String convert(String s, int nRows) {
                if (s == null || s.length() <= nRows || nRows == 1) {
                    return s;
                }
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < nRows; i++) {
                    if (i == 0 || i == nRows - 1) {
                        int index = i;
                        while (index < s.length()) {
                            sb.append(s.charAt(index));
                            index += 2 * (nRows - 1);
                        }
                    } else {
                        int index = i;
                        while (index < s.length()) {
                            sb.append(s.charAt(index));
                            if (index + 2 * nRows - 2 * i - 2 < s.length()) {
                                sb.append(s.charAt(index + 2 * nRows - 2 * i - 2));
                            }
                            index += 2 * (nRows - 1);
                        }
                    }
                }
                return sb.toString();
            }
        }
    }
    
    ############
    
    class Solution {
        public String convert(String s, int numRows) {
            if (numRows == 1) {
                return s;
            }
            StringBuilder ans = new StringBuilder();
            int group = 2 * numRows - 2;
            for (int i = 1; i <= numRows; i++) {
                int interval = i == numRows ? group : 2 * numRows - 2 * i;
                int idx = i - 1;
                while (idx < s.length()) {
                    ans.append(s.charAt(idx));
                    idx += interval;
                    interval = group - interval;
                    if (interval == 0) {
                        interval = group;
                    }
                }
            }
            return ans.toString();
        }
    }
    
  • // OJ: https://leetcode.com/problems/zigzag-conversion/
    // Time: O(N)
    // Space: O(1)
    class Solution {
    public:
        string convert(string s, int numRows) {
            if (numRows == 1) return s;
            int N = s.size(), d = (numRows - 1) * 2;
            string ans;
            for (int i = 0; i < numRows; ++i) {
                int w = 2 * i;
                for (int j = i; j < N;) {
                    ans += s[j];
                    w = d - w;
                    if (!w) w = d;
                    j += w;
                }
            }
            return ans;
        }
    };
    
  • class Solution:
        def convert(self, s: str, numRows: int) -> str:
            if numRows == 1:
                return s
            group = 2 * numRows - 2
            ans = []
            for i in range(1, numRows + 1):
                interval = group if i == numRows else 2 * numRows - 2 * i
                idx = i - 1
                while idx < len(s):
                    ans.append(s[idx])
                    idx += interval
                    interval = group - interval
                    if interval == 0:
                        interval = group
            return ''.join(ans)
    
    ############
    
    class Solution(object):
      def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows <= 1:
          return s
        n = len(s)
        ans = []
        step = 2 * numRows - 2
        for i in range(numRows):
          one = i
          two = -i
          while one < n or two < n:
            if 0 <= two < n and one != two and i != numRows - 1:
              ans.append(s[two])
            if one < n:
              ans.append(s[one])
            one += step
            two += step
        return "".join(ans)
    
    
  • func convert(s string, numRows int) string {
    	if numRows == 1 {
    		return s
    	}
    	n := len(s)
    	ans := make([]byte, n)
    	step := 2*numRows - 2
    	count := 0
    	for i := 0; i < numRows; i++ {
    		for j := 0; j+i < n; j += step {
    			ans[count] = s[i+j]
    			count++
    			if i != 0 && i != numRows-1 && j+step-i < n {
    				ans[count] = s[j+step-i]
    				count++
    			}
    		}
    	}
    	return string(ans)
    }
    
  • function convert(s: string, numRows: number): string {
        if (numRows === 1) {
            return s;
        }
        const ss = new Array(numRows).fill('');
        let i = 0;
        let toDown = true;
        for (const c of s) {
            ss[i] += c;
            if (toDown) {
                i++;
            } else {
                i--;
            }
            if (i === 0 || i === numRows - 1) {
                toDown = !toDown;
            }
        }
        return ss.reduce((r, s) => r + s);
    }
    
    
  • /**
     * @param {string} s
     * @param {number} numRows
     * @return {string}
     */
    var convert = function (s, numRows) {
        if (numRows == 1) return s;
        let arr = new Array(numRows);
        for (let i = 0; i < numRows; i++) arr[i] = [];
        let mi = 0,
            isDown = true;
        for (const c of s) {
            arr[mi].push(c);
    
            if (mi >= numRows - 1) isDown = false;
            else if (mi <= 0) isDown = true;
    
            if (isDown) mi++;
            else mi--;
        }
        let ans = [];
        for (let item of arr) {
            ans = ans.concat(item);
        }
        return ans.join('');
    };
    
    
  • using System.Collections.Generic;
    using System.Linq;
    
    public class Solution {
        public string Convert(string s, int numRows) {
            if (numRows == 1) return s;
            if (numRows > s.Length) numRows = s.Length;
            var rows = new List<char>[numRows];
            var i = 0;
            var j = 0;
            var down = true;
            while (i < s.Length)
            {
                if (rows[j] == null)
                {
                    rows[j] = new List<char>();
                }
                rows[j].Add(s[i]);
                j = j + (down ? 1 : -1);
                if (j == numRows || j < 0)
                {
                    down = !down;
                    j = j + (down ? 2 : -2);
                }
                ++i;
            }
            return new string(rows.SelectMany(row => row).ToArray());
        }
    }
    
  • impl Solution {
        pub fn convert(s: String, num_rows: i32) -> String {
            let num_rows = num_rows as usize;
            if num_rows == 1 {
                return s;
            }
            let mut ss = vec![String::new(); num_rows];
            let mut i = 0;
            let mut to_down = true;
            for c in s.chars() {
                ss[i].push(c);
                if to_down {
                    i += 1;
                } else {
                    i -= 1;
                }
                if i == 0 || i == num_rows - 1 {
                    to_down = !to_down;
                }
            }
            let mut res = String::new();
            for i in 0..num_rows {
                res += &ss[i];
            }
            res
        }
    }
    
    

All Problems

All Solutions