一、题目描述
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L   C   I   R
E T O E S I I G
E   D   H   N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L     D     R
E   O E   I I
E C   I H   N
T     S     G
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路
1. 二维数组
将传入的行数numRows作为二维数组的行数,也就是说numRows值等于内部嵌套的数组个数,例如numRows=4,则创建的二维数组为res=[[], [], [], []].
接下来对数组进行填充:
- 对字符串
s进行遍历,然后将遍历的元素依次添加到二维数组中。 - 首先填充的是内部数组的下标为0位置上的元素,字符串
s遍历的第一个元素添加到第一个数组,第二个元素已添加到第二个数组,第三个元素添加到第三个数组,第四个元素添加到第四个数组。到这里第一轮就结束了,然后反过来开始第二轮,然后到了第五个元素添加到第三个数组(也就是倒数第二个),往后都按照这个套路进行,直到遍历结束。 
三、代码实现
1. 二维数组
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows == 0 or numRows == 1:
            return s
        length = len(s)
        # 创建二维数组
        result = [[] for _ in range(numRows)]
        # 选择指向数组的指针
        n = 0
        for ss in s:
            if n < 0:
                if n >= -numRows:
                    result[n].append(ss)
                    n -= 1
                else:
                    # 逆序循环结束,从下标为1(也就是第二个数组)的数组开始添加
                    n = 1
                    result[n].append(ss)
                    n += 1
            elif n >= numRows:
                # 当n大于二维数组的长度,开始逆序添加,从倒数第二个数组开始
                n = -2
                result[n].append(ss)
                n -= 1
            else:
                result[n].append(ss)
                n += 1
        return ''.join([''.join(num) for num in result])
四、表现
| 方法 | 运行时间 | 表现 | 内存消耗 | 表现 | 
|---|---|---|---|---|
| 1、二维数组 | 76ms | 46.57% | 13.4MB | 34.17% |