看完题目就蒙圈了,所以就直接看了别人的答案
几个答案看下来,基本上有这么三种思路
1.最清晰易懂的一种
string convert(string s, int numRows)
{
if(s.size()<=1||numRows==1)
return s;
int len=s.size(),i,step=1,row=0;
string *str=new string[numRows];
for(i=0;i<len;i++)
{
str[row]+=s[i];
if(row==0)
step=1;
if(row==numRows-1)
step=-1;
row+=step;
}
s.clear();
for(i=0;i<numRows;i++)
s.append(str[i]);
delete[] str;
return s;
}
这种解法可以说是非常巧妙了,我们来看看有哪些可以学习的地方。
首先对特殊情况的优先处理,能够节省不少时间,这个老生常谈了;然后这个算法核心思路是将zipzap之后的每一行都存在一个string类型数组的元素中,最后整合这些元素返回结果,很好理解,但是细节的处理非常高妙,主要是step和row这里的创新设计。每次row到达一个极端之后,step改变正负从而实现zigzag,真正是在模拟zigzag的过程,而不是单纯的找数学规律,这使得解法非常易懂。
而接下来的两种,就不是模拟zigzag了,而是找数学规律,所以比较费解一点。
class Solution {
public:
string convert(string s, int nRows) {
if(nRows == 1) return s;
int len = s.size(), k = 0, interval = (nRows<<1)-2;
string res(len, ' ');
for(int j = 0; j < len ; j += interval)//处理第一行
res[k++] = s[j];
for(int i = 1; i < nRows-1; i++)//处理中间行
{
int inter = (i<<1);
for(int j = i; j < len; j += inter)
{
res[k++] = s[j];
inter = interval - inter;
}
}
for(int j = nRows-1; j < len ; j += interval)//处理最后一行
res[k++] = s[j];
return res;
}
};
我们分析这个解法,他是直接从原来的s里按照题目要求顺序挑选出char并组成一个字符串返回的。首先也是对特殊情况处理,然后涉及到一个位运算的小知识,我们在文末会附上相关总结,现在我们只要知道<<是×的意思。这里interval就是每隔一个周期同一位置字母之间的距离(此处类比波形图,我不造怎么描述更清楚)对于第一行和最后一行,都是相差了一个周期,所以直接加上就好了;但是对于中间几行,引入了一个颇为抽象的变量inter,与interval一起实现上转折和下转折时计算间隔,也是非常巧妙的(我什么时候才能想出这么美的代码啊啊啊啊)
class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1) {
return s;
}
string result;
size_t length = s.length();
for (int i = 0; i < numRows; i++) {
int long_step = 2 * numRows - 2 * (i + 1);
int short_step = i * 2;
int j = i;
while (j < length) {
if (long_step != 0) {
result.push_back(s[j]);
j += long_step;
}
if (j < length) {
if (short_step != 0) {
result.push_back(s[j]);
j += short_step;
}
}
}
}
return result;
}
};
还有第三个······其实这个和第二个有异曲同工之妙啦,有木有发现,其实long_step就是上一个解法中interval-inter啦,而short—step就是inter~~~如果long_step!=0,说明不是最后一行,如果short_step!=0,说明不是第一行,也就是说,和上面一样,把首末两行和中间几行分开处理啦,但是这种解法很巧妙不用分情况讨论~可以说第三种是第二种的优化版本啦~再详细点说,如果是中间几行,也是在两种间隔计算方式之间循环,如果是首末,则long_step和short_step一样都是周期~因为只满足一个if条件,就会隔一个周期在result里塞进一个数。
嗯嗯,附上位运算·位运算~