6.Z字变换(python)

本文介绍了一种将字符串按Z字形排列并重新组合的算法。通过将字符串“LEETCODEISHIRING”按不同行数进行Z字形排列,展示了如何生成新的字符串输出。该算法利用了sinx函数的周期性质,适用于多种行数的变换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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

思路:这个Z可以抽象成sinx,然后利用sinx的周期性就可以求解
f(idx) = f(idx + T)
f(idx) = f(T - idx)

代码

class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        end=''
        n=len(s)
        if numRows<=1:
            return s
        T=numRows*2-2
        res=""
        for i in range(numRows):
            cnt=0
            while(1):
                if cnt*T+i<len(s):
                    res+=s[cnt*T+i]
                else:
                    break
                if i==0 or i==T/2:
                    cnt+=1
                    continue
                if cnt*T+T-i<len(s):
                    res+=s[cnt*T+T-i]
                else:
                    break
                cnt+=1
        return res
                    
### Python 实现 Z 变换 以下是基于提供的引用内容以及专业知识整理的 Python 实现 Z 变换的代码示例: #### 方法一:通过标志位控制方向 这种方法利用了一个 `flag` 变量来控制符分配的方向,当到达最顶端或底端时反转方向。 ```python def convert(s: str, numRows: int) -> str: if numRows < 2: # 如果行数小于2,则无需转换 return s res = [""] * numRows # 创建一个长度为numRows的列表用于存储每一行的结果 i, flag = 0, -1 # 初始化索引i和方向标志flag for c in s: # 遍历输入符串中的每一个符 res[i] += c # 将当前符添加到对应的行 if i == 0 or i == numRows - 1: # 当达到第一行或者最后一行时改变方向 flag = -flag i += flag # 更新索引i,按照flag指示的方向移动 return "".join(res) # 合并所有行的结果并返回 ``` 此方法的核心在于使用变量 `flag` 来动态调整指针的上下移动逻辑[^3]。 --- #### 方法二:模拟 Z 型路径 另一种方式是直接模拟 Z 型的路径变化过程。该算法会根据当前所在的行号决定下一步应该前进还是后退。 ```python def convert(s: str, numRows: int) -> str: if numRows == 1 or numRows >= len(s): # 特殊情况处理 return s rows = [''] * numRows # 定义一个数组用来保存不同行的数据 current_row, step = 0, -1 # 设置初始状态参数current_row表示当前位置;step=-1意味着先向下走一步后再向上回溯 for char in s: # 对于符串里的每个母做如下操作 rows[current_row] += char # 把这个母加到对应位置上去 if current_row == 0 or current_row == (numRows - 1): # 改变行走方向条件判断 step = -step current_row += step # 调整下一个要访问的位置序号 result = ''.join(rows) # 连接所有的子串形成最终答案 return result ``` 上述实现中引入了两个额外的状态变量——`current_row` 和 `step`,分别代表当前所处的行以及步长(正负决定了向上的还是向下的趋势)。每当触碰到边界之后就切换一次运动轨迹[^2]。 --- ### 测试案例 为了验证以上两种方案的有效性,可以采用官方文档给出的例子来进行对比测试。 ```python if __name__ == "__main__": test_cases = [ ("PAYPALISHIRING", 3), ("PAYPALISHIRING", 4), ("A", 1) ] results = [] for case in test_cases: output_1 = convert(*case) output_2 = convert_v2(*case) # 假设第二种方法命名为convert_v2 results.append((output_1, output_2)) print(results) ``` 运行结果应分别为 `"PAHNAPLSIIGYIR"` 和 `"PINALSIGYAHRPI"` 等预期值[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值