【中等】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; } };
总结
- 由于方法二涉及大量的运算,代价是比方法一大的