Z字形变换

2019-08-22  本文已影响0人  潇垚枫语

题目区(源自于leetcode)

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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

思路说明

通过题目解释可以看出规律:输入的字符串以从上到下开始排列,到最后一行后沿着对角线逐渐回到第一行(不包括第一行),循环往复。那么每一行取得数组的下标就有了规律,是一个带有周期性图形重复。那么就可以归纳如下(假设有n行):

从图形我们可以看出周期为pace = n*2-2

第一行

从下标0开始,每个周期只会取到一个字符,每次增加一个周期(n*2-2)

第二行到第n-1行

在每一个周期内只会取到最多两个字符。第一个字符从下标(当前行数j-1)开始,每次增加一个周期(n*2-2);第二个字符从下标(n*2-2-当前行数j+1)开始,每次增加一个周期(n*2-2)

第n行

从下标n-1开始,每次增加一个周期(n*2-2)

源码区

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

char * convert(char * s, int numRows);
main() {
    char input[50] = {"LEETCODEISHIRING"};
    int num = 4 ;
    char * s = convert(input,num);
    printf("%s",s);

}

char * convert(char * s, int numRows) {
    if(numRows==1) {
        return s;
    }
    int size = strlen(s);//数组的长度
    char result[size];
    memcpy(result,s,sizeof(char)*size);
    int pace = 2*numRows-2;//一个周期数据长度
    int j=0;
    while(j<size) { //处理第一行
        *(s++)= result[j];
        j+=pace;
    }
    j = 1;//将行数指向第二行
    for(; j<numRows-1; j++) { //默认除了第一行和第n-1行都有两个数字
        int k1 = j;
        int k2 = pace-k1;
        while(1) {

            if(k1>size-1) { //判断第一个数是否存在,不存在跳出
                break;
            }
            *(s++) = result[k1];
            if(k2>size-1) { //判断第二个数是否存在,不存在跳出
                break;
            }
            *(s++) = result[k2];
            k1+=pace;
            k2+=pace;//向后移动一个周期 
        }
    }
    while(j<size) { //处理最后一行
        *(s++) = result[j] ;
        j+=pace;
    }
    return s-size;
}
上一篇下一篇

猜你喜欢

热点阅读