Z 字形变换(力扣6)

题目描述

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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

解题思路

方法1

观察以上两个示例可以得出结论:每一横行每个字符之间间隔的字符数量都是一定的,所以找到其中的规律就可以迎刃而解。

 第一横行的第一个字符是s字符串的第一个字符,第二横行的第一个字符是s字符串的第二个字符。对于示例二而言,第一横行的L和D之间,D和R之间,间隔5个字符。第二横行E与O,E与I相差3个字符,O与E,I与I相差1个字符,找到这些规律之后,就可以写代码了。

public static String convert(String s, int numRows) {
		if (s.length() < 3 || numRows == 1)
			return s;
		String str = "";
		int rows = 1; // 用来计算第几行
		int num = 2 * numRows - 3; // 第一行和最后一行跳过的个数
		int index = 0; // 当前指针所指的位置
		while (str.length() < s.length()) {
			if (rows == 1 || rows == numRows) {
//				当index超过s的长度之后,表示当前行已经全部遍历完毕
				while (index < s.length()) {
					str += s.charAt(index);
					index += num + 1;
				}
			} else {
				int Upnum = (rows - 2) * 2 + 1; // 向上跳过的个数
				int DownNum = (numRows - rows - 1) * 2 + 1; // 向下跳过的个数
				int flag = -1; // -1 表示向下,1表示向上
				while (index < s.length()) {
					str += s.charAt(index);
					if (flag == -1) {
						index += DownNum + 1;
						flag = 1;
					} else {
						index += Upnum + 1;
						flag = -1;
					}
				}
			}
			index = rows;
			rows++;
		}
		return str;
	}

方法2:

先初始化一个字符串数组,将每个字符放到对应的行即可。具体思路参考下图

public static String convert(String s, int numRows) {
		if (s.length() < 3 || numRows == 1)
			return s;
		String strList[] = new String[numRows];
		for (int i = 0; i < numRows; i++)
			strList[i] = "";
		int rows = 0;
		int flag = 1; // 1 表示向下,-1表示向上
		for (int i = 0; i < s.length(); i++) {
			strList[rows] = strList[rows] + s.charAt(i);
			rows += flag;
			if (rows == numRows - 1)
				flag = -1;
			if (rows == 0)
				flag = 1;
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < numRows; i++) {
			sb.append(strList[i]);
		}
		return sb.toString();
	}

第二种方法实现的思路较简单,所以时间复杂度和内存消耗比方法1好,如果大家也有不错的方法,我们可以一起讨论。 

猜你喜欢

转载自blog.csdn.net/qq_44313091/article/details/107840323