题目:
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 RAnd 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"
.
算法复杂度:O(n)
思路:只遍历一次字符串s,就得到目标字符串。关键是怎么得到offset,以及offset如何使用,用法很巧妙!!
Attention: 用pos < len和 pos +offset < len来作为判断循环是否结束的条件。
AC Code:
class Solution {
public:
string convert(string s, int nRows) {
if (nRows <= 1)
return s;
string str;
int pos = 0;
int len = s.length();
int offset = 0;
for (int i = 0; i < nRows; i++)
{
//for each row, find the elements and add to string str
pos = i;
//太巧妙了,此处就是i + offset 刚好得到和i同行的字符。实际就是 mod - 2*i =2(nRows-1 - i),画图可知。
offset = 2 * (nRows - 1 - i);
//此处刚好循环 len/2*nRows次 所以算法复杂度是 O(nRows * len/2*nRows) = O(n)
while (pos < len)
{
//which mean str = str + s[pos]
str += s.substr(pos, 1);
if (i != 0 && i != nRows - 1 && pos + offset < len)
//if it's not the first or last line, we need add one more,
str += s.substr(pos + offset, 1); //that is str = str + s[pos+offset]
pos += 2 * nRows - 2;
}
}
return str;
}
};
解法二:
算法复杂度:O(nRows*n)
思路://字符串按照Z字型书写,由输入行数决定Z的宽度。要求输出Z字型结果。
//利用同行的余数相同的原理,遍历得到返回结果result. 其实也是取余后距离nRows-1相同的点在同一行
//余数: c = a/b; 余数 r = a - c*b.
Attention: 注意是s中字符索引余数相同,而不是s[j]取余相等!!书写时不要想当然顺手就写。
AC Code:
class Solution {
public:
string convert(string s, int nRows) {
//字符串按照Z字型书写,由输入行数决定Z的宽度。要求输出Z字型结果。
//利用同行的余数相同的原理,遍历得到返回结果result. 其实也是取余后距离nRows-1相同的点在同一行
//余数: c = a/b; 余数 r = a - c*b.
string result;
if(nRows <= 1)
return s;
int ind = s.length() - 1;
int mod = 2 * nRows - 2; //nRows大于1时,循环的模是 n +(n-2),归纳总结可得。
//把取余后余数相同的字符或符合互补条件的字符按顺序依次存入result中
//for(int i == 0; i <= mod/2; i++)
for(int i = 0; i <= nRows - 1; i++)
{
for(int j = 0; j <= ind; j++)
{
/* 此处表达有问题,应该是s中对应索引的模,而不是s中元素。思考时对的,但是敲代码时犯了经验错误,顺手写了s[j]
if((s[j] % mod) == i || ((s[j] % mod) + i == mod ))
*/
if(j % mod == i || (j % mod) + i == mod)
result.push_back(s[j]);
}
}
return result;
}
};