【中等】6-Z字变换 Zigzag Conversion

题目

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)

L   C   I   R
E T O E S I I G
E   D   H   N

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

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

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

L   C   I   R
E T O E S I I G
E   D   H   N

Example

输入: s = "LEETCODEISHIRING", numRows =?4
输出:?"LDREOEIIECIHNTSG"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

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

解法

方法一:逐个字符确定行号

解题思路

确定行数为numRows,字符从第一行开始落下,且后续字符串向下移动,当无法向下时便向上,分别用nunrows个字符串存储每一行的字符,最后连接起来即可。

【中等】6-Z字变换 Zigzag Conversion

代码

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows < 2) return s;
        string result[numRows];
        for(int i = 0; i < numRows; ++i) result[i] = "";
        int curr = 0, dir = 1;
        for(int i = 0; i < s.length(); ++i){
            result[curr] += s[i];
            if(curr == numRows-1) dir = -1;
            else if(curr == 0) dir = 1;
            curr += dir;
        }
        string res = "";
        for(int i = 0; i < numRows; ++i){
            res += result[i];
        }
        return res;
    }
};

方法二:逐行确定字符

解题思路

对于numRows行数据,除了numRows=0和numRows=1外,都可以把groupnum = 2numRows-2个数字分成一组,共n组。此时,对于行号为i,一定有index=i+tgoupnum的字符 (0<=t<=n, 0<=索引<s.length()),且除了第0行和第numRows-1行,每组都有两个字符落在行中,也就是i+(t+1)goupnum-2i = (t+1)*groupnum-i也在这一行,由此,只需要依次输出每组落在行中的字符即可

【中等】6-Z字变换 Zigzag Conversion

代码

class Solution {
public:
    string convert(string s, int numRows) {
        string result = "";
        if(numRows < 2) return s;
        int group_num = numRows+numRows-2, line = 0;
        for(int i = 0; i < numRows; ++i){
            int pos = i;
            while(pos < s.length()){
                result = result+s.substr(pos, 1);
                pos += group_num;
                if(i != 0 && i != numRows-1 && pos-i*2 < s.length()){
                    result = result+s.substr(pos-i*2, 1);
                }
            }
        }
        return result;
    }
};

总结

  1. 由于方法二涉及大量的运算,代价是比方法一大的