LeetCode - 6. ZigZag Conversion

本文详细阐述了zigzag字符串转换算法的解题思路及C程序实现,包括数学推导公式、程序逻辑与运行结果展示。

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

题目:

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

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

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string text, int nRows);

convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".

 

解题思路:

        找出原来字符串s中合适位置的元素,给新的之字形字符串zgStr中的字符按顺序赋值。所以问题的关键即找出原s和新的zgStr之间的对应关系,即数学推导公式

        由于得到之字形结果后,要按行输出结果,所以容易想到,推导zgStr中每行的字符与原s中字符的位置关系。

数学推导过程:

        首先,当numRows等于1或者大于等于s的长度时,返回原来的s即可;

        然后,计算推导公式:

        显然,之字形结果的第一行和最后一行是按原s中间隔 2*numRows-2 依次输出;

        对中间行,可分别得奇数位置与偶数位置直接的递推关系:

        所以原来的思路一直局限于怎么找出这两个关系,并且通过怎样的循环来赋值输出。结果虽然可以分别推导出奇数位置和偶数位置的递推关系,但是无法用一个递推公式推导出合在一起的结果。

    并且原来的思路一直是先判断是否是最后一行,然后赋值输出;再专门对中间行进行处理。但是一直进行不下去。

    后来看了DISCUSS里的解答之后,才忽然明白,不需要推导两个相邻位置的递推关系。

    因为中间行的奇数位置上和第一行、最后一行的关系一样,所以可以一起处理,不需要单独处理开头结果和中间行;并且只需要找到偶数位置与其上一个位置(奇数位置)的关系即可!

        这样先按照间隔 2*numRows-2 输出一个元素,然后判断是不是开头结尾行,若不是再输出一个(即接下来的偶数位置的)。

    而偶数位置与其上一个位置的关系在之前的递推公式中也得到。

 

C程序实现:

char* convert(char* s, int numRows) {
    int sLen = strlen(s);
    int c = 0;  //之字形数组zgStr的下标
         char* zgStr = malloc((sLen+1)*sizeof(char));
    if(numRows == 1 || numRows >= sLen){
        return s;
    }
    else{
        for(int i=1; i<=numRows; i++){
            for(int j=i; j<=sLen; j+=2*numRows-2){
                zgStr[c++] = s[j-1];
                if(i!=1 && i!=numRows && j+2*(numRows-i)<=sLen) //再对中间行的偶数位置单独处理一次
                   		      zgStr[c++] = s[j-1+2*(numRows-i)];
            }
        }
    }
    zgStr[sLen]='\0';   //别忘了最后的结束
    return zgStr;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值