每日leetcode:Z字形变换(python)

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

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

L   C   I   R
E T O E S I I G
E   D   H   N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。

命原字符串为s,行数为numRows

很明显:这是图形是循环的,每个循环节可以被视为一组(如题设例子中的第一组LEET),既然输出是按行输出的,那么我们在读取的时候也考虑按行顺序逐个读取(如题设例子中第一行LCIR),每组的个数可以确定(numRows*2-2),然后每行在s中跳跃读取,只需要注意除开首尾两行,每行中每组都有两个字符(如题设例子中第一组的ET)。

考虑到代码的简洁性,应该将这两类情况处理在同一个循环内部,然后用if进行讨论,这里明显要进行两层循环:按行,按组;组循环在外部的话需要讨论除开完整组之外的剩余字符(如题设例子再多加一个字符,除开完整的4组,还会多一个字符出来),但是行循环为外部循环的话,就不需要考虑这个问题,同时内部的组循环只需要判断是否超出s边界就可以了,因此内部组循环从根据组数计算索引从s中逐个取出相连直到完整组全部取完,变为根据索引是否超出边界就可以了,前者还需要对不完整组进行单独讨论。

繁杂代码(但是由于讨论的情况较多,而且循环采用range的for循环而非while循环,效率更高(才怪):

    def convert(self, s: str, numRows: int) -> str:
        L = len(s)
        conGroup = 2*numRows-2
        if conGroup == 0:
            return s
        numGroup = L//conGroup
        out = ""
        if L == 0:
            return ""
        if L < conGroup:
            out += s[0]
            for i in range(1,numRows-1):
                if i < L:
                    out += s[i]
                if conGroup-i < L:
                    out += s[conGroup-i]
            if L >= numRows:
                out += s[numRows - 1]
            return out
        for i in range(0, numGroup):
            out += s[i*conGroup]
        if L%conGroup>0:
            out += s[(i+1)*conGroup]
        for i in range(1,numRows-1):
            for j in range(0, numGroup):
                out += s[j*conGroup+i]+s[(j+1)*conGroup-i]
            if (j+1)*conGroup+i < L:
                out += s[(j+1)*conGroup+i]
            if (j+2)*conGroup-i < L:
                out += s[(j+2)*conGroup-i]
        for i in range(0, numGroup):
            out += s[i*conGroup+numRows-1]
        if L%conGroup>=numRows:
            out += s[(i+1)*conGroup+numRows-1]
        return out

优化后的代码:

def convert(self, s: str, numRows: int) -> str:
        L = len(s)
        conGroup = 2*numRows-2
        if conGroup == 0:
            return s
        out = ""
        for i in range(0, numRows):
            j = 0
            while i+j < L:
                out += s[i + j]
                if 0<i<numRows-1 and j+conGroup-i<L:
                    out += s[j+conGroup-i]
                j += conGroup
        return out

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值