Leetcode 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".

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

Leetcode ZigZag Conversion_第1张图片     Leetcode ZigZag Conversion_第2张图片

具体来说就是:

Leetcode ZigZag Conversion_第3张图片

关键是要会如何计算各个字符的位置,这就需要数学知识了,根据特殊推导出公式来。
主要是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;            }
}


你可能感兴趣的:(Leetcode ZigZag Conversion)