ZigZag Conversion问题

问题描述:

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

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

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string text, int nRows);

convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".

说说我一开始怎么想的吧,通过观察我发现,在完整的一列到下一个完整的列之间会有一些空白的地方,我把这些空白的长度叫做gap,空白的个数叫做gap_num,观察发现gap=nRows-2,gap_num=nRows-1,知道这个规律以后我们只要创建一个二维数组,以列的形式读入字符串再以行的形式输出字符串就是我们需要的答案了。

#include <string.h>
char* convert(char* s, int numRows) {
    int len = strlen(s), rows = numRows;
    char *bucket = (char *)malloc((len*numRows) * sizeof(char));
    char *p;
    int gap = numRows - 2, gap_num = numRows - 1;
    int i=0, j, k = 0;
    for (p = bucket; p < bucket+len*numRows; p++)
        *p = 0;
    p = bucket;
    if(len==0||numRows==1)
        return s;
    while (s[i] != ‘\0‘) {
        while (rows-->0&&s[i]!=‘\0‘) {
            *p = s[i++];
            p++;
        }
        while (gap_num-->0&&s[i]!=‘\0‘) {
            gap = numRows - 2;
            while (gap-->0)
                p++;
            *p = s[i++];
            p++;
        }
        gap_num = numRows - 1;
        rows=numRows-1;
    }
    char *answer =(char *) malloc((len + 1) * sizeof(char));
    for (i = 0; i<numRows; i++)
        for (j = 0; j<len; j++) {
            if (*(bucket + j*numRows + i) != 0)
                answer[k++] = *(bucket + j*numRows + i);
        }
    answer[k]=‘\0‘;
    return answer;
}

代码写得有点渣,不过这不是我想要的最终的算法嘛,随便写写,能AC就好。AC之后发现这个算法真是有够慢的,那么我当然得想一个更快的算法了。稍微考虑一下我发现,这个算法慢在两个地方,一是中间数组bucket,如果我能不经过中间数组而直接得到结果的话速度应该会快不少。二是空白的处理,想想我之前用while去处理真是太傻了点。

#include <string.h>
char* convert(char* s, int numRows) {
    int len = strlen(s), row = 0;
    int gap=2*numRows-2,gap_1,gap_2=0,i=0,j=0;
    char *answer =(char *) malloc((len + 1) * sizeof(char));
    if(numRows==1||len==0)
        return s;
    while(row<numRows){
        gap_1=gap-gap_2;
        i=row;
        answer[j++]=s[i];
        while(1){
            i=i+gap_1;
            if(i>=len)
                break;
            if(gap_1!=0)
                answer[j++]=s[i];
            i=i+gap_2;
            if(i>=len)
                break;
            if(gap_2!=0)
                answer[j++]=s[i];
        }
        row++;
        gap_2+=2;
    }
    answer[j]=‘\0‘;
    return answer;
}

这是改进后的代码,时间从166ms提升到了9ms,效果还是挺显著的。思路的话简单来说就是通过观察规律直接将原字符串转为需要的答案字符串。我发现的规律是gap(也就是从完整两列之间的距离)为2*numRows-2。完整两列之间同行的数有3个(包括完整列上的数,首行和末行把第二列上的数算两次)。第一个到第二个的距离,我记为gap_1,第二个到第三个记为gap_2。容易看出gap_1+gap_2==gap,并且所在行数每增加1,gap_2就减少2。有了这个规律,就很容易写出上面的代码了。

时间: 2024-10-11 04:20:15

ZigZag Conversion问题的相关文章

No.006 ZigZag Conversion

6. ZigZag Conversion Total Accepted: 98584 Total Submissions: 398018 Difficulty: Easy The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for bette

LeetCode ZigZag Conversion(将字符串排成z字型)

1 class Solution { 2 public: 3 string convert(string s, int nRows) { 4 string a=""; 5 int len=s.length(); 6 if(len<=nRows||nRows==1) return s; //只有n个,不足一个周期||排成一行 7 int teams=len/(nRows*2-2); //teams个完整的周期 8 int rest=len%(nRows*2-2); //最后一个不足

leetcode -day16 ZigZag Conversion

1.  ZigZag Conversion The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line b

【LeetCode】ZigZag Conversion

ZigZag Conversion The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line

LeetCode【6】. ZigZag Conversion --思路图解与java实现

ZigZag Conversion 一.题目如下: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line

64. ZigZag Conversion

ZigZag Conversion The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line

6. ZigZag Conversion

/* * 6. ZigZag Conversion * 2016-8-26 by Mingyang * 觉得这个题目面试的必要性不大,有规律,第一行和最后一行每两个相差2n-2 * 中间的每行除了2n-2有外,中间的一个也有2 * (n - 1 - i) */ public String convert(String s, int numRows) { if (numRows == 1) return s; StringBuilder sb = new StringBuilder(); // s

leetCode 6. ZigZag Conversion 字符串

6. ZigZag Conversion

leetCode 6. ZigZag Conversion 字符串 (上传费劲)

6. ZigZag Conversion 题目:https://leetcode.com/problems/zigzag-conversion/ string convert2(string s, int numRows) { if (s.length() < 2 || numRows < 2) return s; int cycle = 2 * numRows - 2; string tmp; string result; for (int i = 0; i < numRows; i+

ZigZag Conversion --思路图解与java实现

ZigZag Conversion一.题目如下:          The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for b...http://yuedu.baidu.com/album/view/a9e914106c175f0e7cd