LeetCode-中等-6-Z字形变换(C)

我觉得这更像N字形变化。

题目

打空格有点麻烦,WordPress用的html默认清除空格,题目中字符排列请到原题查看:https://leetcode-cn.com/problems/zigzag-conversion

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

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

L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

这题得找规律,例子可以用1234567890,比较方便计算。

row表示行,oldPos表示待分配字符串中的位置,newPos表示新分配字符串中的位置,convertResult为新分配字符串,numRows为总行数。

易得:第一行与最后一行中,每列相差 2*(numRows-1)。
易知:第二行到倒数第二行中,每竖列相差 2*(numRows-1)。
容易看出:第二行到倒数第二行中,每竖列后的第 2*(numRows-1) - 2*(row-1) 位置有字符(这里也可以认为是前2*(row-1)个位置,但实际代码中不好操作)。

举例,对于1234567890字符串中,分成4行,如右表。
第二行的第二列,套公式row+2*(numRows-1),为2+2*3=8,右表该位置也为8。
而对于第三行第一列的后面一位,代入公式row+2*(numRows-1)-2*(row-1),为3+2*3-2*2=5,右表该位置也为5。

17
268
359
40

这样,我们先套一个大循环,遍历每行,再套一个循环,遍历各行中符合公式的值,就可以按顺序算出每个newPos对应的oldPos。

在后面的代码中,双层for循环中的第一个convertResult赋值为列赋值,后面的if内赋值为列后的斜线赋值。

代码

char * convert(char * s, int numRows){
    char *convertResult;
    int row, oldPos, newPos, charLength;
    //初始化
    charLength = strlen(s);
    convertResult = (char*)malloc(sizeof(char)*(charLength+1));
    convertResult[strlen(s)] = '\0';
    newPos = 0;
    //赋值
    if(numRows==1) return s;
    for(row=1;  row<=numRows;   row++){
        for(oldPos=row; oldPos<=charLength;  oldPos+=2*(numRows-1)){
            convertResult[newPos++] = s[oldPos-1];
            if(oldPos+2*(numRows-1)-2*(row-1)<=charLength && row!=1 && row!=numRows){
                convertResult[newPos++] = s[oldPos+2*(numRows-1)-2*(row-1)-1];
            }
        }
    }
    return convertResult;
}

版权声明:
作者:MWHLS
链接:https://mwhls.top/625.html
来源:无镣之涯
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>