Z字形变换

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

解题思路:

(1)对传入的字符串从左到右开始遍历

(2)MIN(numRows, strlen(s)),通过对传入的Z字形行数与传入字符串的大小做判断,取得最小值,来确定Z字形图案有几行,避免出现空行的情况

(3)从左到右迭代字符串,以Z字形的方式,将每一个字符添加到当前行的空列中,可以使用两个变量来控制该动作,一个是cur_row, 控制当前字符可以放置的行,一个是down,可控制Z字形是否需要变换方向

(4)只有向下移动到最下面一行或者向上移动到最上面一行的时候,当前行的方向则需要改变

代码实现如下:

#define MIN(x, y)  (x<y?x:y)
char * convert(char * s, int numRows){
    int len=strlen(s);
    int rows=MIN(len, numRows);
    // 对传入的字符串与行数比大小,取最小的值,是为了保证之后申请的存放列表的每一行都是有效的,
    // 避免Z字形列表中出现空行的情况
    if(rows == 0 || rows ==1){ 
    // 考虑特殊的情况,比如说,传入的字符串是空的,或者是只有一行的情况,这样的话,直接将原有字符串输出即可
        return s;
    }
    char *ret_string=NULL;
    ret_string=malloc(len+1);
    memset(ret_string, 0, len+1);
    char string[rows][len+1];
    memset(string, 0sizeof(string));
    int down=0;//控制遍历字符串的时候,是否需要变换方向
    int cur_row=0;//确定当前字符存放的行
    int i;
    for(i=0; i<len;i++){
        string[cur_row][strlen(string[cur_row])]=s[i];
        if(cur_row == 0 || cur_row== rows-1){
            //当向上遍历到最上面或者向下遍历到最小面的时候,需要改变遍历的方向
            if(down==0){
                down=1;
            }else{
                down=0;
            }
        }
        cur_row+=down?1:-1;// 确认当前行号
    }
    
    for(i=0; i<rows;i++){
        strcat(ret_string, string[i]);
    }

    return ret_string;
}


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

posted on 2020-03-04 14:23  PigDragon  阅读(506)  评论(0编辑  收藏  举报