6. Z 字形变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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;
}
浙公网安备 33010602011771号