ZigZag Conversion-LeetCode

本文介绍了一种将字符串以Zigzag模式排列并重新读取的方法。通过将字符串转换为指定行数的Zigzag模式,然后逐行读取以形成新的字符串。文章提供了两种实现思路及对应的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P   A   H   N
A P L S I I G
Y   I   R
And then read line by line:  "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string text, int nRows);
convert("PAYPALISHIRING", 3)  should return  "PAHNAPLSIIGYIR" .

Subscribe to see which companies asked this question.



题目理解:将输入的字符串,字符顺序重排后输出,可以简单理解为将一维向量转换为了二维的矩阵,最后将二维矩阵又拼接成一维向量返回。
重排规则:zigzag,之字形扫描。
解决的大体思路:根据输入的之子宽度参数nRows,将text不同下标的字符散列到不同行的字符串中,最后按行重新拼接起来。为了方便追加字符,每一行使用的是StringBuilder result[nRows]。
eg:
0       8       16      
1     7 9     15 17      
2   6   10   14   18      
3 5     11 13     19      
4       12       20    
 


具体的将,再散列字符到不同行时,有两种思路可以考虑:
(1)根据输入的nRows,将text分组,在组内有相同位置的字符会被追加到同一行字符中。如上图所示,nRows=5,那么每组的长度为2*5-2=8;可以看到每8个字符都是一组相同的形状和散列位置排布。我们计算组内每个字符应当放入哪行字符串,同时完成向result[]散列的过程。注意到,在同一组内,字符放入result[]的行号会有增加和减小两个过程。在使用本思路精确计算式应当注意。
代码:
public class Solution {
	public String convert(String s, int numRows) {
		StringBuilder[] result=new StringBuilder[numRows];
		char[] array=s.toCharArray();
		for(int i=0;i<numRows;i++)result[i]=new StringBuilder(s.length());
		//对每一个stringbulider初始化
		int i=0,loc=0;
		while(i<s.length()){
			for(loc=0;loc<numRows && i<s.length();i+=1,loc+=1){
				result[loc].append(array[i]);
			}//由0开始的行号上升过程,同时字符串指示下标也要移动
			for(loc=numRows-2;loc>0 && i<s.length();i+=1,loc-=1){
				result[loc].append(array[i]);
			}//由numRows-2开始的行号下降过程,同时字符串指示下标也要移动
		}
		for(i=1;i<numRows;i++){
			result[0].append(result[i]);
		}
		return result[0].toString();
	}
}

(2)注意到,在字符散列进result[]的行号会有增加和减小两个过程,利用边界值0和nRows-1,来改变待散列指示标记loc的移动方向,即可完成正确散列。值得注意的是,使用该思路需要留意nRows为1的情况,需要在代码的最开始做出特殊情况处理。
代码:
public class Solution {
	public String convert(String s, int numRows) {
		if(s.length()<=numRows||numRows==1)return s;
		StringBuilder[] result=new StringBuilder[numRows];
		char[] array=s.toCharArray();
		int len=s.length();
		for(int i=0;i<numRows;i++)result[i]=new StringBuilder(len);
		int i=0,loc=0,step=1;
		while(i<len){	
			result[loc].append(array[i]);
			if(loc==numRows-1)step=-1;	//下标减小
			if(loc==0)step=1;			//下标增加
			loc+=step;
			i+=1;
		}
		for(i=1;i<numRows;i++){
			result[0].append(result[i]);
		}
		return result[0].toString();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值