题目描述
.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)
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”.
这个题目的意思就是这个图,让你把它摆成一个锯齿状,然后把每一行的有效字符输入到一个新的字符串 中即可。锯齿状是这个意思:
分析
这道题大家仔细看,其实有一个规律,就是有一个恒定的偏移量为 2(line-1) ,然后每一行的偏移量等于前一个下标+当前行的当前偏移量,当前行的偏移量第一次偏移是 恒值-2*i ,第二次就是 恒值减去上一次的 偏移量。
其实也可以看成,当前行的初始偏移量是 恒值 - 2*i ,之后的每次偏移量都是 恒值减去上一次偏移量。
这个方法,有个特殊的地方就是,最后一行初始偏移量计算出来是0,但是真正偏移量是 2(line-1) 也是恒值。
其实很简单,更新偏移量,一直遍历到最后一行答案就出来了,因为这个方法遍历下来,把每一行的有效字符都输入到了 result中。
时间复杂度O(N),空间O(1)。
代码
string convert(string & s, int numRows)
{
if (numRows == 1)
{
return s;
}
string ret;
int size = s.size();
int jumplen = 2 * (numRows - 1); // 一个偏移量恒值
ret.resize(s.size());
int retpos = 0;//偏移量 ,一部分是第二次跳的偏移量。 所以first 是控制第几次跳
int spos = 0;// 这个用来记录当前次跳转的偏移量
int k = 0;//这个 str中的下标
for (int i = 0; i < numRows; ++i)
{
spos = jumplen - 2 * i;
spos = (spos>0) ? spos : jumplen;
k = i;
while (k< size)
{
ret[retpos++] = s[k];
k = k + spos;
spos = (spos<jumplen) ? jumplen - spos : spos;
}
}
return ret;
}