每日一练——Z 字形变换(python)

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

比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
每日一练——Z 字形变换(python)_第1张图片
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

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

思路1:
看到题目的第一时间,想到要使用二维数组来存储最终排列的形状。那么,首先要确定二维数组的行数与列数。很明显行数在输入参数已经给出,我们要求得的就是其列数,设行数为r,输入的字符串长度为sLen。可以得知:
每两列的字符数:r+(r-2)=2r-2
则,所需的列数为:sLen/(2r-2)+1。
接下来将第一个字符存入数组的[0][0]位置,可以发现,竖着存时,每存r-1个数后,存储的方向相反,列数+1。设置一个计数器与一个符号变量,每当计数器计数到2时,符号反向,列数+1。其余情况则行数+=符号变量。
最后遍历一遍二维数组即可得到答案。

def convert(s, r):  # s:字符串 r:行数
    if len(s) == 0 or r < 2:
        return s
    res = ""  # 存放结果
    sLen = len(s)  # 所给字符串的长度
    cols = 2*sLen // (2 * r - 2) + 1
    mtx = [["" for _ in range(cols)] for _ in range(r)]
    a, b = 0, 0  # mtx中的坐标
    mtx[0][0] = s[0]
    count = 0
    symbol = +1
    for x in s[1:]:
        if count == 2:
            count = 0
            symbol = -symbol
            b += 1
        a = a + symbol
        mtx[a][b] = x
        count += 1

    for x in mtx: # 遍历一次mtx
        for y in x:
            if y != "":
                res += y
    return res

缺点:时间复杂度与空间复杂度都较高,有优化的空间

思路2:
有没有办法只遍历一次字符串就得到我们想要的结果呢?有。
我们最终需要得到的只是一个字符串,并不需要建立二维数组存储,不需要得知其具体图形,只需要知道每一行有什么字符即可。遍历一次字符串,每一行所求序列与按遍历先后加入该行的序列相同。即,每次将遍历到的字符按先后加入其所在的行数即可。解法如下:

def convert(self, s: str, numRows: int) -> str:
        if len(s) == 0 or r < 2:
            return s
        res = ["" for _ in range(numRows)]
        i, flag = 0, -1
        for c in s:
            res[i] += c
            if i == 0 or i == numRows - 1: 
            	flag = -flag
            i += flag
        return "".join(res)

你可能感兴趣的:(每日一练,python学习)