力扣 Z 字形变换

该博客讨论了如何使用Python解决力扣上的Z字形字符串变换问题。内容包括介绍Z字形排列的规则,给出不同解决方案,如暴力求解(矩阵模拟)和优化方法(仅记录当前行数),并分享了实现过程和最终通过的例子。
摘要由CSDN通过智能技术生成

Z 字形变换

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

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

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

string convert(string s, int numRows);

示例 1:

输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

示例 2:

输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:

输入:s = "A", numRows = 1
输出:"A"

暴力解决,矩阵模拟Z,最后遍历

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if(len(s) <= numRows or numRows == 1):return s

        loop = numRows*2 -2
        need = len(s)//loop + 1

        matrix = [[] for i in range(numRows)]
        for m in matrix:
            for i in range((numRows-1) * need):m.append('')
        
        currColumn,currLine,flag = 0,0,0
        for i in s:
            matrix[currLine][currColumn] = i
            if(currLine == numRows-1):
                currLine -= 1
                currColumn += 1
                flag = 1         
                continue
            if(currLine == 0 and flag == 1):
                flag = 0
                currLine += 1     
            elif(flag == 1):
                currLine -= 1
                currColumn += 1   
            else:
                currLine += 1

        res = ''
        for M in matrix:
            for m in M:
                if(m != ''):res += m

        return res

结果:丢人丢到家

执行结果:通过


执行用时:992 ms, 在所有 Python3 提交中击败了5.12%的用户
内存消耗:21.9 MB, 在所有 Python3 提交中击败了5.04%的用户
通过测试用例:1157 / 1157

去除矩阵储存,改用只记录当前的行数

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if(len(s) <= numRows or numRows == 1):return s

        dp,dpStr = [],[]
        for i in s:
            dp.append(0)
            dpStr.append(i)
        
        currLine,flag = 0,0
        for i in range(len(s)):
            dp[i] = currLine
            if(currLine == 0 and flag == 1):
                flag = 0
            elif(currLine == numRows -1 ):
                flag = 1

            if(flag == 0):
                currLine += 1
            else:
                currLine -= 1

        res = ''

        # 进行排序,4次循环
        for i in range(numRows):
            for m in range(len(dp)):
                if(dp[m] == i):
                    res += dpStr[m]

        return res

结果:还是丢人
执行结果:通过

执行用时:664 ms, 在所有 Python3 提交中击败了7.62%的用户
内存消耗:15.2 MB, 在所有 Python3 提交中击败了30.61%的用户
通过测试用例:1157 / 1157

优解:

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows < 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)
结果:思路同理,但是这里的flag和res用的灵活
执行结果:通过
执行用时:44 ms, 在所有 Python3 提交中击败了93.40%的用户
内存消耗:15.1 MB, 在所有 Python3 提交中击败了60.00%的用户
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值