题目:
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; } };