LeetCode 10 Z字变换

  拿到题目的后最容易想到就是先转换成Z字型再添加,此种方法不做赘述,效率一般。其次能够想到利用数学规律来当索引直接变换,一般规律如下

易得有n行,m个z时字符串长度为(2n-2)m+n,其中有

  1. 第一行与最后一行只有m+1个,其他为2*m+1个
  2. 每一行第一列均有且只有一个
  3. 第二行到第n-1行的非首列(第i行第j列)后的每两个数字,都相对(2n-2)*j+1对称,分别为(2n-2)*j+1+i与(2n-2)*j+1-i

结合给出的字符串不一定刚好组成m个Z字,可能不全,加入判断写出代码如下

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if not s:
            return ""
        if numRows == 1:return s
        res = ""
        m = int((len(s)-numRows)/(2*numRows-2)) + 1
        for i in range(numRows):
            for j in range(m+1):
                if i == 0 or i == numRows-1:
                    if (2*numRows-2)*j+i < len(s):
                        res += s[(2*numRows-2)*j+i]
                elif j == 0:
                    if (2*numRows-2)*j+i <len(s):
                        res += s[(2*numRows-2)*j+i]
                else:
                    if (2 * numRows - 2) * j - i < len(s):
                        res += s[(2 * numRows - 2) * j - i]
                    if (2 * numRows - 2) * j + i < len(s):
                        res += s[(2*numRows-2)*j + i]
        return res

效率一般,打败50%左右

 

在题解里面看到另外一种解法,也是找规律,但是实现方法不同,即以(2n-2)为一片断来判断添加,代码如下

def convert(s: str, numRows: int):
    if not s:
        return ""
    if numRows == 1: return s
    split_s_len = numRows * 2 - 2
    data = []
    n = len(s)

    for i in range(0, n, split_s_len):
        data.append(s[i:i + split_s_len])
    # print(data)
    res = ""
    for i in range(numRows):
        for tmp in data:
            if i < len(tmp):
                if i == 0 or i == numRows - 1:
                    res += tmp[i]
                else:
                    res += tmp[i]
                    if split_s_len - i < len(tmp):
                        res += tmp[split_s_len - i]
    return res

时间复杂度打败百分之七八十左右,相对上述解法减少了很多判断与求索引的操作

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值