LeetCode:6.Z字形变换

题目

LeetCode: ZigZag Conversion

将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:

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

之后从左往右,逐行读取字符:”PAHNAPLSIIGYIR”

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

string convert(string s, int numRows);

示例:

示例1:

输入: s = “PAYPALISHIRING”, numRows = 3
输出: “PAHNAPLSIIGYIR”

示例2:

输入: s = “PAYPALISHIRING”, numRows = 4
输出: “PINALSIGYAHRPI”

解释:

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

思路

这是一个找规律题,每次字母差是有规律的
第一行字母之间差为2n - 2
第二行子母之间差为2n - 42交替
……
倒数第三行字母间差为42n - 6交替
倒数第二行字母间差为22n - 4交替
倒数第一行字母间差为2n - 2

总结一下规律,除了第一行和最后一行,每次交替的值的和为2n - 2,第一行和最后一行为2n - 2,每一行第一次相差的值比前一行少2

代码

查看更多LeetCode代码

char* convert(char* s, int numRows) {
    assert(s);
    int size = strlen(s) + 1;
    char* ret = (char*)malloc(size);
    if (numRows == 1)
    {
        //单独处理特殊字符串
        strncpy(ret, s, size);
        return ret;
    }
    assert(ret);
    char* cur = ret;
    char* get = s;
    int row_count = numRows * 2 - 2;//增量一直在变,总结一下规律
    //假设numRows传入为n,可以画图找规律
    //第一行增量为2n-2
    //第二行增量为2n-4,2依次交替
    //第三行增量为2n-6,4依次交替
    //……每行增量减少2,直至增量变为2
    //第n-1行增量为2,2n-4依次交替
    //第n行增量比较特殊,为2n-2
    int increment = numRows * 2;//每次的增量
    int increment_tmp = 0;//作为增量的临时存储变量
    for (int i = 0; i < numRows; i++)
    {
        //get作为获取当前字符的指针
        get = s + i;
        if (increment > 2)
        {
            //每次的增量减少2
            increment -= 2;
        }
        else if (increment == 2)
        {
            //当前一次增量为2,将增量置为2n-2
            increment = row_count;
        }
        increment_tmp = increment;
        while (get - s < size - 1)
        {
            *cur++ = *get;
            get += increment_tmp;
            //变换增量
            increment_tmp = row_count - increment_tmp;
            if (increment_tmp == 0)
            {
                increment_tmp = row_count;
            }
        }
    }
    *cur = '\0';
    return ret;
}

猜你喜欢

转载自blog.csdn.net/Boring_Wednesday/article/details/80472752