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)
http://blog.csdn.net/zhouworld16/article/details/14121477
第0行和最后一行中,前一个下标的值和后一个下标的值相差 2*(nRows-1),以第0行为例,前一个下标为0, 后一个下标为 0+2*(4-1)=6。中间行中,前一个下标的值和后一个下标的值需要根据这个下标是该行中的奇数列还是偶数列来计算。
以第2行为例,第一个下标是2,后一个下标所处列为1,是奇数列,因此从这个下标到下一个下标相差的值是它们所处的行i下面的所有行的点的个数,即2 * (nRows - 1 - i)。在这里,nRows-1是为了遵循0下标开始的原则。这样,我们可以求得这个奇数列的下标为 2+2*(4-1-2)=4。同理,当我们要计算4之后的下标时,我们发现下一个所处的是偶数列2,从这个下标到下一个下标相差的值其实是它们所处的行i上面的所有行的点的个数,即2 * i。因此,该列的下标计算为4+2*2=8。
除第一行和最后一行,每一行奇数列后面的间隔:2 * (nRows - 1 - i), 偶数列后面的间隔:2 * i。
上图中nRows=4, i = 0,1,2,3
第0行,间隔为2*(4-1-0)=6,数为0, 6;
第1行,第一列后面间隔为2*(4-1-1)=4,第二列后面的间隔为2*1=2... 数为1, 5, 7, 11 ...
第2行,第一列后面间隔为2*(4-1-2)=2,第二列后面的间隔为2*2=4... 数为2, 4, 8, 10 ...
解题重点:将字符串转换为下标的排列,并发现每一行的规律。
//
// start: convert string to zigzag string
string convert(string s, int nRows) {
{
int size = s.size();
if(size <= 1 || nRows <= 1)
return s;
int length = s.size();
string result = "";
for(int i = 0; i < length; i++)
{
int index = i;
for(int k = 1; ; k++) // 判断是奇数还是偶数,所以从1开始计数,而不是while(index)
{
if(i == 0 || i == nRows-1) // 第0行和最后一行
index += 2*(nRows-1);
else
{
if(k & 0x01) // 奇数
index += 2*(nRows-1);
else
index += 2*(i-1);
}
if(index < length)
res += s[index]; // 按新数组顺序找
else
break;
}
}
return result;
}
// end
//