#6 Z字形变换

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

L   C   I   R
E T O E S I I G
E   D   H   N

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

我的垃圾代码(python):

def convert(self, s: str, numRows: int) -> str:
        cur_return = []
        if numRows > 2:
            for row in range(0,numRows):
                if row==0 or row==numRows-1:
                    for i in range(row,len(s),2*numRows-2):
                        cur_return.append(s[i])
                else:
                    a = row
                    b = 2*numRows - row - 2
                    while a<len(s) or b<len(s):
                        if a < len(s):
                            cur_return.append(s[a])
                            a = a + 2*numRows - 2
                        if b < len(s):
                            cur_return.append(s[b])
                            b = b + 2*numRows - 2
        else:
            if numRows == 2:
                cur_return.append(s[0::2])
                cur_return.append(s[1::2])
            if numRows == 1:
                cur_return.append(s)
        return ''.join(cur_return)

 优质代码(python):

class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """

        if numRows == 1 or numRows >= len(s):
            return s
        L = [''] * numRows
        index, step = 0, 1
        for x in s:
            L[index] += x
            if index == 0:
                step = 1
            elif index == numRows - 1:
                step = -1
            index += step
        return ''.join(L)

 官方解答(java):

class Solution {
    public String convert(String s, int numRows) {

        if (numRows == 1) return s;

        StringBuilder ret = new StringBuilder();
        int n = s.length();
        int cycleLen = 2 * numRows - 2;

        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j + i < n; j += cycleLen) {
                ret.append(s.charAt(j + i));
                if (i != 0 && i != numRows - 1 && j + cycleLen - i < n)
                    ret.append(s.charAt(j + cycleLen - i));
            }
        }
        return ret.toString();
    }
}

 

### Z字形变换算法实现与解释 #### 算法概述 Z字形变换是一种特殊的字符串排列方式,其核心在于按照特定的行数 `numRows` 将字符串重新排列成一种类似于“Z”形状的形式。最终目标是从这种排列中按照行优先的方式读取出新的字符串。 对于输入字符串 `s` 和行数 `numRows` 的约束条件为: - $1 \leq |s| \leq 1000$ - $1 \leq numRows \leq 1000$ 当 `numRows = 1` 或者字符串长度小于等于 `numRows` 时,可以直接返回原字符串[^3]。 --- #### 算法逻辑 该问题可以通过模拟字符分配的过程来解决。具体步骤如下: 1. **初始化存储结构** 创建一个列表(数组),其中每个元素代表一行的内容。初始为空字符串。 2. **遍历字符串并分配字符** 使用一个变量记录当前字符应放置在哪一行,并通过方向标志控制上下移动的趋势。如果到达顶部或底部,则改变方向。 3. **拼接结果** 遍历完成后,将每一行的结果依次连接起来形成最终字符串。 这种方法的时间复杂度为 $O(n)$,空间复杂度也为 $O(n)$,因为需要额外的空间存储每行的数据[^4]。 --- #### Python 实现代码 以下是基于上述逻辑的 Python 实现代码: ```python def convert(s: str, numRows: int) -> str: if numRows == 1 or len(s) <= numRows: # 特殊情况处理 return s rows = [''] * numRows # 初始化每行为空字符串 current_row = 0 # 当前行索引 going_down = False # 方向标志,默认向下 for char in s: rows[current_row] += char # 将字符加入对应行 # 判断是否达到边界并调整方向 if current_row == 0 or current_row == numRows - 1: going_down = not going_down # 更新当前行号 current_row += 1 if going_down else -1 return ''.join(rows) # 合并所有行得到结果 ``` --- #### 示例解析 假设输入字符串为 `"LEETCODEISHIRING"`,行数为 `3`,则执行过程如下: 1. 初始化三行数据:`['', '', '']` 2. 开始遍历字符串并将字符逐一放入对应的行中: - `'L'` 放入第 0 行 → `[L, , ]` - `'E'` 放入第 1 行 → `[L, E, ]` - `'E'` 放入第 2 行 → `[L, E, E]` - `'T'` 变换方向放回第 1 行 → `[L, ET, E]` ... 3. 最终各行列状态为: ``` Row 0: LCIRE Row 1: TOESII Row 2: GEDHN ``` 4. 拼接结果为 `"LCIRETOESIIGEDHN"` --- #### 边界情况讨论 1. 如果 `numRows = 1`,无需任何操作直接返回原始字符串。 2. 如果字符串长度小于等于 `numRows`,同样不需要特殊处理,只需简单分隔即可[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值