LeetCode第六题:Z 字形变换 【6/1000 python】

简介: LeetCode第六题:Z 字形变换 【6/1000 python】

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

在力扣(LeetCode)的题库中,"Z 字形变换"是一个独特的字符串处理问题,它考验着对字符串操作的精确控制和对问题模型的理解。本文将深入探讨这个问题,并提供一个高效的解决方案。

问题描述

给定一个字符串和一个行数,要求你按照从上往下、从左到右的顺序,进行 Z 字形排列。

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

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

之后,你的输出需要按行读取,输出一个新的字符串,即 "PAHNAPLSIIGYIR"

解题思路

观察 Z 字形排列,我们可以发现,除了第一行和最后一行外,其他每一行中间都会夹杂一个来自斜线上的字符。每一“轮”Z字形的字符数是固定的,为 2 * numRows - 2(除去首尾两行后,上下两部分各占据 numRows - 1,加上首尾两行即得公式)。

基于这个观察,我们可以通过计算每个字符在 Z 字形排列中的位置,从而构建出最终的字符串。

解题步骤

  1. 创建一个数组,长度等于给定的行数,用于存储每行的字符。
  2. 遍历给定字符串的每个字符,计算出该字符应该放置在哪一行。
  3. 按照从上到下、从左到右的顺序,将字符添加到对应行的字符串中。
  4. 最后,将这些行连接起来,形成最终的字符串。

代码示例

初步尝试:直接模拟

最初可能会尝试直接按照 Z 字形排列的逻辑去模拟整个过程,例如,尝试为每一行和斜线创建单独的存储空间,然后尝试填充它们。

def convert_v1(s: str, numRows: int) -> str:
    # 特殊情况处理
    if numRows == 1 or numRows >= len(s):
        return s
 
    # 初始化存储结构
    z_matrix = [[] for _ in range(numRows)]
    row, down = 0, True
 
    for c in s:
        z_matrix[row].append(c)
        if row == numRows - 1:
            down = False
        elif row == 0:
            down = True
        row += 1 if down else -1
 
    # 结果拼接
    result = ''
    for r in z_matrix:
        result += ''.join(r)
    return result

问题:这个方法试图通过控制方向变量 down 来模拟“Z”字形的折返运动,但实际上它忽略了在 numRows 为 1 或者输入字符串很短时的特殊情况,容易造成索引错误或者不必要的复杂度。

改进:合并斜线到行

认识到斜线上的字符其实可以直接并入对应的行中,不需要单独处理斜线部分,这样可以简化代码和逻辑。

def convert_v2(s: str, numRows: int) -> str:
    if numRows == 1 or numRows >= len(s):
        return s
    
    rows = [''] * numRows
    current_row, step = 0, -1
    
    for char in s:
        rows[current_row] += char
        if current_row == 0 or current_row == numRows - 1:
            step = -step
        current_row += step
        
    return ''.join(rows)

这个版本已经比较接近最终的解法了,但仍然可以在细节上进行优化和规范,例如增加注释来提高代码的可读性。

最终版本:增加注释和细节优化

在最终版本中,我们添加了必要的注释,并确保代码清晰、简洁、易于理解。

def convert(s: str, numRows: int) -> str:
    # 处理特殊情况,提高效率
    if numRows == 1 or numRows >= len(s):
        return s
    
    # 初始化存储每行字符串的列表
    rows = [''] * numRows
    # 初始化当前行和行进方向
    current_row, step = 0, -1
    
    for char in s:
        rows[current_row] += char
        # 到达Z字形的顶部或底部时,改变方向
        if current_row == 0 or current_row == numRows - 1:
            step = -step
        current_row += step
        
    # 将所有行的字符串连接并返回
    return ''.join(rows)
 
# 示例测试代码
s = "PAYPALISHIRING"
numRows = 3
print(convert(s, numRows))  # 输出: "PAHNAPLSIIGYIR"

代码解释

  • 初始化一个列表 rows,长度为 numRows,用于存储每一行的字符串。
  • 使用 current_row 来追踪当前字符应该放在哪一行。step 用于控制行号的增减,实现“Z”字形的折返运动。
  • 遍历字符串中的每个字符,根据当前行号添加到相应的行字符串中。当当前行号为第一行或最后一行时,改变行号的增减方向。
  • 最后,使用 ''.join(rows) 将所有行的字符串连接成一个字符串。

结语

"Z 字形变换"问题通过模拟字符串的重新排列过程,不仅测试了对字符串处理的能力,也考察了对问题的逻辑分析和转换能力。如果本文对你有帮助,点赞是对作者最大的鼓励哦!


欢迎关注微信公众号 数据分析螺丝钉

相关文章
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
63 6
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
125 2
|
4月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
72 7
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
33 4
|
4月前
|
算法 Python
【Leetcode刷题Python】 LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色
本文介绍了LeetCode 2038题的解法,题目要求在一个由'A'和'B'组成的字符串中,按照特定规则轮流删除颜色片段,判断Alice是否能够获胜,并提供了Python的实现代码。
58 3
|
4月前
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
26 3
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - II. 从上到下打印二叉树 II
本文提供了一种Python实现方法,用于层次遍历二叉树并按层打印结果,每层节点按从左到右的顺序排列,每层打印到一行。
41 3
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - I. 从上到下打印二叉树
本文介绍了使用Python实现从上到下打印二叉树的解决方案,采用层次遍历的方法,利用队列进行节点的访问。
37 2
|
4月前
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
30 1
|
4月前
|
Python
【Leetcode刷题Python】LeetCode 478. 在圆内随机生成点
本文介绍了LeetCode 478题的解法,题目要求在给定圆的半径和圆心位置的情况下实现在圆内均匀随机生成点的功能,并提供了Python的实现代码。
35 1