这个题是个智力题,重要的是找规律,我来描述一下问题吧:
给一个字符串S 和行数n ,按照题中的格式构成n行的形状,形状大概如下: (3行)
然后按照水平方向取出,最后返回 “PAHNAPLSIIGYIR”
我觉得将输入的字符串直接返回好像和最后要得到的结果一样,不过这种做法万万不可。我们还是按照规律来找吧,规律如下:
1.第一层和最后一层:
可以看出第一层和最后一层比别的层数的元素少了一半左右,所以这两层是特殊的层,应该分别来计算。、
2.第二层至倒数第二层:
这些层的排列是有规律的,我参照上图来说吧,第二行开始开始时’A‘,第二行第2个元素是‘P’,第三个是‘L’,此时n=3,i=1(表示'A'所在的行数,程序中肯定是从第0行开始计算的,所以 i =1 ,表示 第一行),则可知:
A和P的距离是 2*(n-i-1) = 4 , P和L的距离是 2*i = 2
到了L点的时候和A点的情况一样,因为两者的位置构成了循环,我们可以循环去找后面的每个点;
当n=4的时候,大家也可以去试试,规律还是一样的,分两种情况去讨论。
class Solution {
public:
string convert(string s, int numRows) {
int slen = s.size();
string ret;
if(slen <= 0 || numRows < 1)
{
return ret;
}
int row = numRows;
if(row == 1)
{//row=1的时候单独处理一下
for(int i=0; i<slen;++i)
{
//cout<<s[begin];
ret.push_back(s[i]);
}
return ret;
}
for(int i = 0; i < row; ++i)
{
if(i==0 || i == (row-1) )
{//第一层和最后一层
int begin = i;
while(begin < slen)
{//row=1的时候无法跳出循环的,所以上面单独处理了row=1的情况
//cout<<s[begin];
ret.push_back(s[begin]);
begin += 2*(row-1);
}
}
else
{
int begin = i;
while(begin < slen)
{
//cout<<s[begin];
ret.push_back(s[begin]);
begin += 2*(row-i-1);
if(begin >= slen)
{
break;
}
//cout<<s[begin];
ret.push_back(s[begin]);
begin += 2*i;
}
}
}
return ret;
}
};
我觉得大家平时可以多做做智力题,这样不仅可以开发思维,而且还能增强对事物的判读能力。我发现,这些智力题中都包含着一些简单的算法知识,可能我们说不出来到底是什么算法,我们在做这样的题的过程中算法能力会有很显著的增长。让我们享受编程的快乐吧。