【中等】6-Z字变换 Zigzag Conversion
题目
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)
L C I R
E T O E S I I G
E D H N
And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
Example
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
来源:力扣(LeetCode)
链接:https://leetcode.com/problems/zigzag-conversion
解法
方法一:逐个字符确定行号
解题思路
确定行数为numRows,字符从第一行开始落下,且后续字符串向下移动,当无法向下时便向上,分别用nunrows个字符串存储每一行的字符,最后连接起来即可。
代码
class Solution {
public:
string convert(string s, int numRows) {
if(numRows < 2) return s;
string result[numRows];
for(int i = 0; i < numRows; ++i) result[i] = "";
int curr = 0, dir = 1;
for(int i = 0; i < s.length(); ++i){
result[curr] += s[i];
if(curr == numRows-1) dir = -1;
else if(curr == 0) dir = 1;
curr += dir;
}
string res = "";
for(int i = 0; i < numRows; ++i){
res += result[i];
}
return res;
}
};
方法二:逐行确定字符
解题思路
对于numRows行数据,除了numRows=0和numRows=1外,都可以把groupnum = 2numRows-2个数字分成一组,共n组。此时,对于行号为i,一定有index=i+tgoupnum的字符 (0<=t<=n, 0<=索引<s.length()),且除了第0行和第numRows-1行,每组都有两个字符落在行中,也就是i+(t+1)goupnum-2i = (t+1)*groupnum-i也在这一行,由此,只需要依次输出每组落在行中的字符即可
代码
class Solution {
public:
string convert(string s, int numRows) {
string result = "";
if(numRows < 2) return s;
int group_num = numRows+numRows-2, line = 0;
for(int i = 0; i < numRows; ++i){
int pos = i;
while(pos < s.length()){
result = result+s.substr(pos, 1);
pos += group_num;
if(i != 0 && i != numRows-1 && pos-i*2 < s.length()){
result = result+s.substr(pos-i*2, 1);
}
}
}
return result;
}
};
总结
- 由于方法二涉及大量的运算,代价是比方法一大的