Leetcode ZigZag Conversion

来源:互联网 发布:上海乐其网络怎么样 编辑:程序博客网 时间:2024/06/06 08:40
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".

所谓的ZigZag,就是以倒N型这样的:

     

具体来说就是:

关键是要会如何计算各个字符的位置,这就需要数学知识了,根据特殊推导出公式来。
主要是3个公式:
1 之字形行数为nRows,那么每次倒N重复样出现前的间隔字符为ziglen = nRows*2-2,如上图有8行,第一个倒N包含abcdefghijklmn,第二个倒N从接下来的o

开始,我们知道字符o与前面第一个倒N的首个字符位置相差正好ziglen;
2 第一行和最尾一行都是存放一个字符的,所以存储的字符为间隔为ziglen的字符
3 中间行是需要额外存储多一个字符的,存储的字符位置是: ziglen + j - 2*i(其中i为行数,j为该行第几个字符了)

代码:

char* convert(char* s, int numRows) {    int l=strlen(s);if(l<3||l<=numRows||numRows<=1)return s;int i,j;char *p=(char *) malloc ((l+10)*sizeof(char));memset(p,'a',sizeof(p));int index=0;int ziglen=2*numRows-2;for(i=0;i<numRows;i++){   for(j=i;j<l;j+=ziglen)   {p[index++]=s[j];   if(i!=0&&i!=(numRows-1)&&(ziglen+j-2*i)<l)     p[index++]=s[ziglen+j-2*i];}}p[index]='\0';return p;}

下面输出倒N型:

类似上面分析,只不过在输出时注意空格的输出:

1 之字形行数为nRows,那么每次倒N重复样出现前的间隔字符为ziglen = nRows*2-2,如上图有8行,第一个倒N包含abcdefghijklmn,第二个倒N从接下来的o
开始,我们知道字符o与前面第一个倒N的首个字符位置相差正好ziglen;
2 第一行和最尾一行都是存放一个字符的,所以存储的字符为间隔为ziglen的字符,两个非空字符之间相差zigspce=nRows-2个空格;
3 中间行是需要额外存储多一个字符的,存储的字符位置是: ziglen + j - 2*i(其中i为行数,j为该行第几个字符了)。当第一个非空字符靠近左边时,在第1-第zigspace-i列有空格;当靠近右边时有i-1个空格:

void dis(char* s, int numRows){ if(numRows==1)cout<<s;int l=strlen(s);if(l==0||numRows<1)cout<<"NONE";  int ziglen=2*numRows-2;  int zigspace=numRows-2;  int i,j,k;  for(i=0;i<numRows;i++){   for(j=i;j<l;j+=ziglen)   {cout<<s[j];    if(i!=0&&i!=numRows-1&&ziglen+j-2*i<l)    {  for(k=0;k<zigspace-i;k++)    cout<<" ";cout<<s[ziglen+j-2*i];for(k=0;k<i-1;k++) cout<<" ";}//中间行输出:先输出第一个,再是空格,最后还是N型上的字符else    {for(k=0;k<zigspace;k++)   cout<<" ";}//第一行和最后一行空格   } cout<<endl;            }}


0 0