将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

    比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:

    1. L C I R
    2. E T O E S I I G
    3. E D H N

    之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:”LCIRETOESIIGEDHN”。

    请你实现这个将字符串进行指定行数变换的函数:

    string convert(string s, int numRows);
    示例 1:

    输入: s = “LEETCODEISHIRING”, numRows = 3
    输出: “LCIRETOESIIGEDHN”

    示例 2:

    输入: s = “LEETCODEISHIRING”, numRows = 4
    输出: “LDREOEIIECIHNTSG”
    解释:

    1. 输入: s = "LEETCODEISHIRING", numRows = 4
    2. 输出: "LDREOEIIECIHNTSG"
    3. 解释:
    4. L D R
    5. E O E I I
    6. E C I H N
    7. T S G

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/zigzag-conversion

    思路:
    对于Z字形,可以按多个以下形状组成,对于第一行和最后一行,我们仅须每次偏移2*numRows -2,对于第j个形状的第i行:则偏移i2*numRows-2 - i

    1. 0 2*n-2
    2. 1 ……
    3. 2 n+3
    4. 3 n+2
    5. 4 n+1
    6. …… n
    7. n-1

    复杂度分析:
    时间复杂度O(n)
    空间复杂度O(1)

    1. var convert = function (s, numRows) {
    2. if (numRows === 1) return s;
    3. let ans = "";
    4. const len = s.length;
    5. let looplen = 2 * numRows - 2;
    6. for (let j = 0; j < len; j += looplen) {
    7. ans += s[j];
    8. }
    9. for (let i = 1; i < numRows - 1; i++) {
    10. for (let j = 0; j + i < len; j += looplen) {
    11. ans += s[j + i];
    12. if (j + looplen - i < len) {
    13. ans += s[j + looplen - i];
    14. }
    15. }
    16. }
    17. for (let j = numRows - 1; j < len; j += looplen) {
    18. ans += s[j];
    19. }
    20. return ans;
    21. };