Leetcode:6. Z 字形变换 C语言实现 2020.2.11

 

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/*
自己的想法
eg. LEETCODEISHIRING"    长度为16
1)行数为几,就开几个队列(为什么想到队列呢?因为想着先进先出来着 但其实只进不用出 最后遍历就好了)

        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
rows=3  0 1 2 1 0 1 2 1 0 1 2  1  0  1  2  1
rows=4  0 1 2 3 2 1 0 1 2 3 2  1  0  1  2  3
rows=5  0 1 2 3 4 3 2 1 0 1 2  3  4  3  2  1
中间元素的值表示放在哪个队列里

2)开了一个数组 找到存储队列的规律  
3)将字符串里的元素按照规律放到各个队列里
4)依次遍历各个队列,读出其中元素
*/

char * convert(char * s, int numRows){
    if(strlen(s) <= numRows || numRows < 2){
        return s;
    }

    struct queue{
        char data[strlen(s)];
        int front;
        int rear;
    };

    struct queue q[numRows];
    for(int i = 0; i < numRows; i++){
        q[i].front = q[i].rear = 0;
    }

    int cycleLen = 2*numRows-2;
    int a[cycleLen];
    for(int i = 0; i < cycleLen; i++){
        if(i < numRows){
            a[i] = i;
        }else{
            a[i] = (numRows-2) -(i-numRows);
        }
    }

    // for(int i = 0; i < cycleLen; i++){
    //     printf("%d ", a[i]);
    // }
    // printf("\n");


    for(int i = 0; i < strlen(s); i++){
        q[a[i%cycleLen]].data[q[a[i%cycleLen]].rear] = s[i];
        q[a[i%cycleLen]].rear++;
    }

    char *newS = s;
    int lenNewS = 0;
    for(int i = 0; i < numRows; i++){
        for(int j = 0; j < (q[i].rear-q[i].front); j++){
            newS[lenNewS++] = q[i].data[j];
        }
    }
    
    return newS;
}

 

 

/*
改进:
没有必要用队列,用一个普通的数据结构就好了,一个记录数据,一个记录长度
*/

char * convert(char * s, int numRows){
    if(strlen(s) <= numRows || numRows < 2){
        return s;
    }

    struct string{
        char data[strlen(s)];
        int length;
    };

    struct string q[numRows];
    for(int i = 0; i < numRows; i++){
        q[i].length = 0;
    }

    int cycleLen = 2*numRows-2;
    int a[cycleLen];
    for(int i = 0; i < cycleLen; i++){
        if(i < numRows){
            a[i] = i;
        }else{
            a[i] = (numRows-2) -(i-numRows);
        }
    }

    for(int i = 0; i < strlen(s); i++){
        q[a[i%cycleLen]].data[q[a[i%cycleLen]].length++] = s[i];
    }

    char *newS = s;
    int lenNewS = 0;
    for(int i = 0; i < numRows; i++){
        for(int j = 0; j < (q[i].length); j++){
            newS[lenNewS++] = q[i].data[j];
        }
    }

    return newS;
}

Leetcode:6. Z 字形变换 C语言实现 2020.2.11_第1张图片

 

此官方题解相对于自己解法的优点:仅仅用了一个新的变量存储方向,碰到边界换向即可  这个题解爱了爱了

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if(len(s) <= numRows or numRows < 2):
            return s

        #创建一个列表,元素个数为numRows,初始化为空串,按照规律添加每个字符串的元素
        list = ["" for _ in range(numRows)] 

        #遍历字符串,分别放入各个子字符串中
        row = 0
        direction = 0
        for i in range(len(s)):            
            list[row] += s[i]
            if(row == 0 or row == numRows-1):  #到了边界,改变方向
                direction = not direction
            row += (1 if direction else -1) 

        #拼接成新的字符串
        newS = ""
        for i in range(len(list)):
            newS += list[i]

        return newS

 

 

Leetcode:6. Z 字形变换 C语言实现 2020.2.11_第2张图片

自己也是按照这种方法做的,只是下标弄的太乱,所以后来换了思路。

Leetcode:6. Z 字形变换 C语言实现 2020.2.11_第3张图片

你可能感兴趣的:(LeetCode)