第六题:Z字形变换(Zigzag Conversion)

题目描述:

将给定的字符串 s 以指定的行数 numRows 进行“Z字形”排列,然后按行读出字符串并返回。

示例:

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

  2. 输入:s = "PAYPALISHIRING", numRows = 4
    输出:"PINALSIGYAHRPI"

要求: 你需要将字符串 s 按照 numRows 行的Z字形排列,并返回按行读取的结果。

解题思路

方法1:模拟
  1. 特殊情况处理

    • 当 numRows 为 1 时,直接返回字符串,因为没有Z字形效果。
  2. 创建一个数组

    • 创建一个二维数组 rows,用于存放每行的字符。
  3. 模拟遍历

    • 使用一个变量 currentRow 来记录当前行,另一个变量 goingDown 来指示是否需要向下移动行数。
    • 遍历字符串中的每个字符,根据 goingDown 的状态决定是向下还是向上移动。
  4. 构建结果

    • 遍历二维数组,将每行的字符拼接成结果字符串。

C 语言实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* convert(char* s, int numRows) {
    int len = strlen(s);
    if (numRows == 1 || numRows >= len) return s;
    
    char** rows = (char**)malloc(numRows * sizeof(char*));
    for (int i = 0; i < numRows; i++) {
        rows[i] = (char*)malloc((len + 1) * sizeof(char));
        rows[i][0] = '\0';
    }
    
    int currentRow = 0;
    int goingDown = 0;
    
    for (int i = 0; i < len; i++) {
        strcat(rows[currentRow], (char[]){s[i], '\0'});
        if (currentRow == 0 || currentRow == numRows - 1) goingDown = !goingDown;
        currentRow += goingDown ? 1 : -1;
    }
    
    char* result = (char*)malloc((len + 1) * sizeof(char));
    result[0] = '\0';
    for (int i = 0; i < numRows; i++) {
        strcat(result, rows[i]);
        free(rows[i]);
    }
    free(rows);
    
    return result;
}

Java 实现

public class Solution {
    public String convert(String s, int numRows) {
        if (numRows == 1 || numRows >= s.length()) return s;
        
        StringBuilder[] rows = new StringBuilder[numRows];
        for (int i = 0; i < numRows; i++) {
            rows[i] = new StringBuilder();
        }
        
        int currentRow = 0;
        boolean goingDown = false;
        
        for (char c : s.toCharArray()) {
            rows[currentRow].append(c);
            if (currentRow == 0 || currentRow == numRows - 1) {
                goingDown = !goingDown;
            }
            currentRow += goingDown ? 1 : -1;
        }
        
        StringBuilder result = new StringBuilder();
        for (StringBuilder row : rows) {
            result.append(row);
        }
        
        return result.toString();
    }
}

Python 实现

def convert(s: str, numRows: int) -> str:
    if numRows == 1 or numRows >= len(s):
        return s
    
    rows = [''] * numRows
    currentRow = 0
    goingDown = False
    
    for char in s:
        rows[currentRow] += char
        if currentRow == 0 or currentRow == numRows - 1:
            goingDown = not goingDown
        currentRow += 1 if goingDown else -1
    
    return ''.join(rows)

时间复杂度

时间复杂度: 所有这些实现方法的时间复杂度为 (O(n)),其中 (n) 是字符串 s 的长度。由于每个字符都被访问一次,时间复杂度是线性的。

空间复杂度: 空间复杂度为 (O(n)) 来存储最终的结果和各行的字符。对于每个字符,我们都需要一个地方来存储,所以总体空间复杂度是线性的。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰魄雕狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值