将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
/* 解题思路: 一个字符串 “0123456789ABCDEF”,转为zigzag 当 n = 3 时: 0 4 8 C 1 *3 5 *7 9 *B D *F 2 6 A E 除了第一行和最后一行没有中间形成之字型的数字外, 其他都有,而首尾两行中相邻两个元素的index之差跟行数是相关的, 为 2 * nRows - 2, 根据这个特点,我们可以按顺序找到所有的无*号元素在元字符串的位置, 将他们按顺序加到新字符串里面。对于*号元素出现的位置也是有规律的, 每个*号元素的位置为 j + 2 * nRows - 2 - 2 * i, 其中,j为前一个*号元素的列数,i为当前行数。 比如当n = 3中的那个*号元素,它的位置为 1 + 2 * 4 - 2 - 2 * 1 = 5,为原字符串的正确位置。 当我们知道所有无*号元素和*号元素位置的正确算法,我们就可以一次性的把它们按顺序都加到新的字符串里面。 */ #include<iostream> #include<string> using namespace std; class Solution { public: string convert(string s, int nRows) { if (nRows <= 1) return s; string res = ""; int size = 2 * nRows - 2; for (int i = 0; i < nRows; ++i) { for (int j = i; j < s.size(); j += size) { res += s[j]; int tmp = j + size - 2 * i; if (i != 0 && i != nRows - 1 && tmp < s.size()) res += s[tmp]; } } return res; } }; int main() { string str; int n; cin >> str; cin >> n; cout << Solution().convert(str, n) << endl; system("pause"); return 0; }