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;
}

  

原文地址:https://www.cnblogs.com/277223178dudu/p/11392663.html