将一个给定字符串根据给定的行数,以从上往下,从左到右进行Z字型排列。

该题出自LeetCode算法题第6题

https://leetcode-cn.com/problems/zigzag-conversion/

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

在我刚看见这个题的时候首先想到的是暴力破解,但是总觉得不太优雅。于是开始整理其中的规律。

不管怎么想都会用到String.charAt(index);

既然字符串不是固定的,那是否可以用下标代替呢?于是乎

0		4		8		12	
1	3	5	7	9	11	13	15	
2		6		10		14		

这个规律其实并不难。但是如果行数不为3呢?

0			6			12
1		5	7		11	13
2	4		8	10		14
3			9			15

这就又头疼了

而且第一个的规律还要在第二个适用。

好吧。我就不买关子了。我就直接将我的思考草稿贴出来吧

//		3
//0		0		4		8		12				(3+1)*0	(3+1)*1	(3+1)*2
//1		1	3	5	7	9	11	13	15			(3+1)*0+-1[-1 1]	(3+1)*1+-1[3 5]	(3+1)*2+-1[7 9]
//2		2		6		10		14				(3+1)*0+2	(3+1)*1+2	(3+1)*2+2
//		
//		4
//0		0			6			12				(4+2)*0	(4+2)*1	(4+2)*2
//1		1		5	7		11	13				(4+2)*0+-1	(4+2)*1+-1	(4+2)*2+-1
//2		2	4		8	10		14				(4+2)*0+-2	(4+2)*1+-2	(4+2)*2+-2
//3		3			9			15				(4+2)*0+3	(4+2)*1+3	(4+2)*2+3
//		
//		5
//0		0				8				16		(5+3)*0
//1		1			7	9			15	17		(5+3)*0+-1
//2		2		6		10		14		18		(5+3)*0+-2
//3		3	5			11	13			19		(5+3)*0+-3
//4		4				12				20		(5+3)*0+4
//		
//		6
//0		0					10				18	20	(6+4)*0
//1		1				9	11			17		21	(6+4)*0+-1
//2		2			8		12		16			22	(6+4)*0+-2
//3		3		7			13	15				23	(6+4)*0+-3
//4		4	6				14					24	(6+4)*0+-4
//5		5					15					25	(6+4)*0+5

以上草稿看懂第一个三行的就可以理解了。只不过每个例子中的中间行需要注意一下。

就是第一列只能加,不能减,不然就会出现多余的负数。

既然思路出来了,那么后面就是代码实现了。

package com.leetcode;

/**
 * 将一个给定字符串根据给定的行数,以从上往下,从左到右进行Z字型排列。
 * 示例
 * "LEETCODEISHIRING"
 * 排列
 * L C I R
 * ETOESIIG
 * EDHN
 * @author HF
 *
 */
public class LeetCodeDemo06 {

	public static void main(String[] args) {
//		3
//0		0		4		8		12				(3+1)*0	(3+1)*1	(3+1)*2
//1		1	3	5	7	9	11	13	15			(3+1)*0+-1[-1 1]	(3+1)*1+-1[3 5]	(3+1)*2+-1[7 9]
//2		2		6		10		14				(3+1)*0+2	(3+1)*1+2	(3+1)*2+2
//		
//		4
//0		0			6			12				(4+2)*0	(4+2)*1	(4+2)*2
//1		1		5	7		11	13				(4+2)*0+-1	(4+2)*1+-1	(4+2)*2+-1
//2		2	4		8	10		14				(4+2)*0+-2	(4+2)*1+-2	(4+2)*2+-2
//3		3			9			15				(4+2)*0+3	(4+2)*1+3	(4+2)*2+3
//		
//		5
//0		0				8				16		(5+3)*0
//1		1			7	9			15	17		(5+3)*0+-1
//2		2		6		10		14		18		(5+3)*0+-2
//3		3	5			11	13			19		(5+3)*0+-3
//4		4				12				20		(5+3)*0+4
//		
//		6
//0		0					10				18	20	(6+4)*0
//1		1				9	11			17		21	(6+4)*0+-1
//2		2			8		12		16			22	(6+4)*0+-2
//3		3		7			13	15				23	(6+4)*0+-3
//4		4	6				14					24	(6+4)*0+-4
//5		5					15					25	(6+4)*0+5
		
		String str = "LEETCODEISHIRING";
		int rowNum = 3;
		String zStr = getZstr(str, rowNum);
		System.out.println(zStr);
	}
	
	public static String getZstr(String str,int rowNum) {
		long startTime = System.nanoTime();
		//获取字符串长度
		int length = str.length();
		//重组字符串数组
		char[] strChar = new char[length];
		//数组下标
		int index = 0;
		//循环行数
		for(int i=0; i<rowNum; i++) {
			//每行的列数
			int count = 0;
			while(true) {
				//第一行和最后一行的算法一致,中间行数每次循环需要多添加一列
				if(i>0 && i<rowNum-1) {
					int indexNum = (2*rowNum-2)*count-i;
					//判断下标是否超出原字符串长度
					if(indexNum >= length) {
						break;
					}
					//中间行第一次只能算加  相减下标为负数(去除)
					if(indexNum > 0) {
						strChar[index] = str.charAt(indexNum);
						index++;
					}
				}
				int indexNum = (2*rowNum-2)*count+i;
				if(indexNum >= length) {
					break;
				}
				strChar[index] = str.charAt(indexNum);
				count++;
				index++;
			}
		}
		long endTime = System.nanoTime();
		System.out.println("运行时长: " + (endTime-startTime) + " ns");
		return String.copyValueOf(strChar);
	}
}

运行结果

你们没有看错,就是 ‘’纳秒‘’。一毫秒都不到

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值