算法练习(4):ZigZag Conversion

先上题

算法练习(4):ZigZag Conversion_第1张图片

这道题我第一眼看根本没看懂,我一开始还以为全部竖着从上到下写,然后偶数列空一个写一个。。。唉,然后就傻傻的按那思路写了代码,当然没过。后来上网查了一下才知道是要Z型转置,也就是把Z按左斜45度线对称的形状。好吧,弯路走的有点多,还好也不难。



分析与思路:第一想法肯定是用个二维char数组把字符串按这个图形规规矩矩走一遍,然后双层循环把非空字符按左右上下拼接。这个方法也不是不能行,就是二维数组的列数要提前算好跟行数以及字符串总长度的关系,用个flag标记往下还是往上走。挺麻烦的,我一开始确实走了这条路,很容易越界什么的,列数没算对吧。后来我想了一下,作了两个优化,第一点是可以改用vector,这样就不用算二维数组的列数了,第二点就是在往上走的时候我根本就不用在二维数组中真的斜上走啊!因为最后读取是是同一行内从左到右读取非空字符,根本就可以直接直上走的。这样问题就被简化了,不用再往上走的时候列数加行数减,只需要根据是否到边界判断一下flag的值,然后根据flag的值判断现在该行增还是行减,列数根本都不用管,因为可以用vector的push_back(char)。代码实现如下:

class Solution {
public:
	string convert(string s, int numRows) {
		if (numRows == 1) return s;
		vector* temp=new vector[numRows];
		bool flag = 1;
		int nowRow = 0;
		for (int i = 0; i < s.length(); i++) {
			temp[nowRow].push_back(s[i]);
			if (flag) {
				if (nowRow + 1 == numRows) {
					nowRow--;
					flag = 0;
				}
				else {
					nowRow++;
				}
			}
			else {
				if (nowRow - 1 == -1) {
					nowRow++;
					flag = 1;
				}
				else {
					nowRow--;
				}
			}
		}
		string result(s.length(), ' ');
		for (int i = 0; i < numRows; i++) {
			for (int j = 0; j < temp[i].size(); j++) {
				cout << temp[i][j];
			}
			cout << endl;
		}
		int k = 0;
		for (int i = 0; i < numRows; i++) {
			for (int j = 0; j < temp[i].size(); j++) {
				result[k++] = temp[i][j];
			}
		}
		return result;
	}
};


你可能感兴趣的:(算法练习)