Description:
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 R
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 s, int numRows);
Example 1:
Input: s = "PAYPALISHIRING", numRows = 3 Output: "PAHNAPLSIIGYIR"
Example 2:
Input: s = "PAYPALISHIRING", numRows = 4 Output: "PINALSIGYAHRPI" Explanation: P I N A L S I G Y A H R P I
描述:
给定行数的情形下,字符串"PAYPALISHIRING"可以表示为如下所示的之字形格式:
P A H N A P L S I I G Y I R
逐行拼接后的字符串为“PAHNAPLSIIGYIR”。
编写转换程序,该程序以字符串和给定行数为输入,并输出转换后的字符串。
string convert(string s, int numRows);
示例1:
输入: s = "PAYPALISHIRING", numRows = 3 输出: "PAHNAPLSIIGYIR"
示例2:
输入: s = "PAYPALISHIRING", numRows = 4 输出: "PINALSIGYAHRPI" 解释: P I N A L S I G Y A H R P I
方法1:按列排列
最直观的想法,是逐列排列字符,最终按行拼接后显示。
class Solution { public: string convert(string s, int numRows) { if(numRows == 1) return s; vector<string> rows(min(numRows, (int)s.length())); int row = 0; string ans = ""; int goDown = 1; for(int i = 0; i < s.length(); i++) { rows[row].push_back(s[i]); if(goDown) { row++; }else{ row--; } if(row >= numRows) { goDown = 0; row = numRows - 2; } if(row < 0) { goDown = 1; row = 1; } } for(int i = 0; i < rows.size(); i++) { ans.append(rows[i]); } return ans; } };
时间复杂度为O(n),空间复杂度为O(n),运行时间16ms。
方法二:按行访问
本方法的思路是先访问第一行中的字符,接着访问第二行的字符,以此类推。。。
对于所有的整数k:
第一行字符的索引为k(2*numRows - 2)
最后一行字符的索引为k(2*numRows - 2) + numRows - 1
中间行元素的索引为k(2*numRows - 2) + i和(k+1)(2⋅numRows−2)−i处。
class Solution { public: string convert(string s, int numRows) { if(numRows == 1 || s.length() == 0 || s.length() == 1) return s; int n = s.length(); int cycle = 2 * numRows - 2; string ret; for(int i = 0; i < numRows; i++) { for(int j = 0; i + j < n; j += cycle) { ret.push_back(s[i + j]); if(i != 0 && i != numRows - 1 && j + cycle -i < n) { ret.push_back(s[j + cycle - i]); } } } return ret; } };
时间复杂度为O(n),空间复杂度为O(n)。