【LeetCode】6. Z 字形变换

leetcode

 

解题思路

Z字形变换的核心在于方向模拟行索引的动态调整。通过维护一个方向数组控制行号的增减,实现字符的逐行填充。具体步骤如下:

  1. 边界处理:当行数为1或字符串为空时直接返回原字符串。
  2. 方向控制:使用方向数组direction = {1, -1}模拟字符填充时的上下移动(向下时行号递增,向上时行号递减)。
  3. 行填充:遍历字符串,将每个字符添加到对应的行数组中,并根据边界条件调整方向。
  4. 结果合并:将所有行的字符按顺序拼接成最终结果。

关键代码解析

func convert(s string, numRows int) string {
    if numRows == 1 || len(s) <= numRows {
        return s // 边界条件直接返回
    }

    // 初始化行存储数组
    rows := make([][]byte, numRows)
    row, direction := 0, 1 // 初始方向向下(行号递增)

    for i := 0; i < len(s); i++ {
        rows[row] = append(rows[row], s[i])
        // 方向反转条件(到达顶部或底部)
        if row == 0 {
            direction = 1 // 向下移动
        } else if row == numRows-1 {
            direction = -1 // 向上移动
        }
        row += direction // 更新行号
    }

    // 合并所有行的字符
    result := make([]byte, 0)
    for _, r := range rows {
        result = append(result, r...)
    }
    return string(result)
}

复杂度分析

指标说明
时间复杂度 O(n) 单次遍历字符串,合并操作线性时间
空间复杂度 O(n) 存储所有字符(与原字符串等长)

示例验证

func main() {
    // 示例1
    s1 := "PAYPALISHIRING"
    fmt.Println(convert(s1, 3)) // 输出: "PAHNAPLSIIGYIR"

    // 示例2
    fmt.Println(convert(s1, 4)) // 输出: "PINALSIGYAHRPI"

    // 示例3
    s2 := "A"
    fmt.Println(convert(s2, 1)) // 输出: "A"

核心逻辑说明

  1. 方向控制机制

    • 初始方向为向下(direction=1),行号递增。
    • 当行号到达底部(row=numRows-1)时,方向改为向上(direction=-1)。
    • 当行号到达顶部(row=0)时,方向恢复向下。
  2. 字符填充过程
    以输入 s="PAYPALISHIRING", numRows=3 为例:

    • P → 行0,方向向下。
    • A → 行1,继续向下。
    • Y → 行2(到达底部),方向改为向上。
    • P → 行1,继续向上。
    • 最终各行数据:["PAHN", "APLSIIG", "YIR"]
  3. 边界处理优化

    • 当 numRows=1 时直接返回原字符串,避免无效计算。
    • 使用 len(s) <= numRows 提前终止无意义的Z字形变换(如示例3)。

扩展讨论

对比其他解法

方法优点缺点适用场景
方向模拟法 逻辑直观,代码简洁 需要存储所有行数据 常规开发场景
数学规律法 无需存储中间数据(直接计算) 需处理复杂模运算 内存敏感场景

数学规律法的实现思路

若采用数学规律法,需根据字符索引 i 计算其所在行:
周期 = 2*numRows - 2
行号 = i % 周期            (当行号 < numRows)
     = numRows-2 - (i % 周期 - numRows + 1) (否则)

但该方法的实现复杂度较高,需处理大量边界条件。


通过方向模拟法,代码简洁且易于维护,是解决Z字形变换问题的推荐方案。该方案完美覆盖所有测试用例,且适用于大规模输入场景。

posted @ 2025-03-28 17:11  云隙之间  阅读(56)  评论(0)    收藏  举报