LeetCode 6 Z字形变换

LeetCode 6 Z字形变换

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

  • 输入:s = “LEETCODEISHIRING”, numRows = 3

    L   C   I   R         0   4   8      12  
    E T O E S I I G       1 3 5 7 9  11  13 15
    E   D   H   N         2   6   10     14
    

    输出:“LCIRETOESIIGEDHN”

  • 输入:s = “LEETCODEISHIRING”, numRows = 4

    L     D     R          0     6       12
    E   O E   I I          1   5 7    11 13
    E C   I H   N          2 4   8 10    14
    T     S     G          3     9       15
    

    输出: “LDREOEIIECIHNTSG”

  • 思路一:当行数为0或者n-1时,方向发生反向转折

    从左到右按题目给定顺序下、斜上、下、斜上方向迭代存储字符串,将每个字符放置到合适的位置,最后从上到下按行遍历存储的字符串数组即可。

class Solution {
public:
    string convert(string s, int numRows) {
        vector<string> rows(min(numRows, int(s.size()))); // 防止s的长度小于行数
        if(numRows == 1) return s;
        int cur_row = 0;
        bool flag = false;
        for(auto c : s)
        {
            rows[cur_row] += c;
            // 当前行cur_row为0或numRows -1时,箭头发生反向转折
            if(cur_row == 0 || cur_row == numRows - 1) flag = !flag;
            //flag为真往下一行,为假往上一行
            cur_row += flag ? 1 : -1;
        }

        string res;
        for(auto row : rows) res += row;
        return res;
    }
};
  • 思路二:等差数列找规律

    将字符转换成数字,如右侧所示,可发现:

    • 对于第一行和最后一行,是公差为 2(n−1) 的等差数列,首项是0n−1
    • 对于第i(0<i<n−1),是两个公差为 2(n−1)的等差数列交替排列,首项分别是 i2n−i−2

    每个字符遍历一遍,所以时间复杂度是O(n).

class Solution {
public:
    string convert(string s, int numRows) {
        string res;
        if (numRows == 1) return s;
        for (int j = 0; j < numRows; j ++ )
        {
            if (j == 0 || j == numRows - 1)
            {
                for (int i = j; i < s.size(); i += (numRows-1) * 2)
                    res += s[i];
            }
            else
            {
                for (int k = j, i = numRows * 2 - 1 - j - 1;
                        i < s.size() || k < s.size();
                        i += (numRows - 1) * 2, k += (numRows - 1) * 2)
                {
                    if (k < s.size()) res += s[k];
                    if (i < s.size()) res += s[i];
                }
            }
        }
        return res;
    }
};
  • 写法二:起始下标是行号,中间层的下标间距也可以看做是step-2*行数2*行数交替。
class Solution {
public:
    string convert(string s, int numRows) {
        string res;
        if(numRows == 1) return s;
        int n = s.size(), step = 2 * (numRows - 1);
        for(int i = 0; i < numRows; i++)
        {
            for(int j = i; j < s.size(); j += step)
            {
                res.push_back(s[j]);
                int step2 = i ? step - 2 * i : 0;
                if(step2 && j + step2 < n)
                    res.push_back(s[j + step2]);
            }
        }
        return res;
    }
};
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读