LeetCode刷题day006 (Jieky)

LeetCode第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
*/
import java.util.List;
import java.util.ArrayList;

public class ZigZagConversion{
     
	public static void main(String[] args){
     
		String str = "LEETCODEISHIRING";
		ZigZagConversion zzc = new ZigZagConversion();
		// LDREOEIIECIHNTSG
		String ret = zzc.convert02(str,4);
		System.out.println(ret);
	}
	
	// 优化第二个实现
	public String convert03(String s, int numRows) {
     
		if (s == null) return null;
		if (numRows == 1 ||s.equals("")) return s;
		// 字符图形的周期
		int cycle = numRows * 2 - 2;
		// 字符串转数组
		char[] strChar = s.toCharArray();
		// 获取字符串长度,开辟新字符串缓存
		int strLen = s.length();
		StringBuffer str = new StringBuffer();
		// 按行追加数据
		for (int strIdx=0;strIdx<numRows;strIdx++){
     
			int startIdx = strIdx;
			while(startIdx < strLen){
     
				str.append(strChar[startIdx]);
				// 一个周期内,非第一行和最后一行的行会有两个元素
				if (strIdx != 0 && strIdx != numRows-1)
					// 第二个元素不能超出最大索引
					if (startIdx + cycle - 2 * strIdx < strLen)
						str.append(strChar[startIdx + cycle - 2 * strIdx]);
				startIdx = startIdx + cycle;
			}
		}
		
		return str.toString();
	}
	
	// 按周期规律和下标规律
	public String convert02(String s, int numRows) {
     
		// 输入检验
		if (s == null) return null;
		if (numRows == 1 ||s.equals("")) return s;
		
		// 字符图形的周期
		int cycle = numRows * 2 - 2;
	
		// 判断s形成z后的最大行数,并生成对应的StringBuilder
		List<StringBuffer> strList = new ArrayList<>(); 
		for (int i = 0; i < Math.min(numRows,s.length());i++){
     
			strList.add(new StringBuffer());
		}
		
		char[] strChar = s.toCharArray();
		
		// 求出第一行数据在原字符串中的索引
		int strLen = s.length();
		
		for (int i=0,strIdx=0;i<strList.size() && strIdx<numRows;i++,strIdx++){
     
			int startIdx = strIdx;
			while(startIdx < strLen){
     
				strList.get(strIdx).append(strChar[startIdx]);
				// 一个周期内,非第一行和最后一行的行会有两个元素
				if (strIdx != 0 && strIdx != numRows-1)
					// 第二个元素不能超出最大索引
					if (startIdx + cycle - 2 * strIdx < strLen)
						strList.get(strIdx).append(strChar[startIdx + cycle - 2 * strIdx]);
				startIdx = startIdx + cycle;
			}
		}
		
		// 对numRow个StringBuilder进行合并
		StringBuffer str = new StringBuffer();
		for(StringBuffer sb : strList){
     
			str.append(sb);
		}
		return str.toString();
	}
	
	// 按照Z字方向规律
	public String convert01(String s, int numRows) {
     
		// 输入检验
		if (s == null) return null;
		if (numRows == 1 ||s.equals("")) return s;
		 
		// 判断s形成z后的最大行数,并生成对应的StringBuilder
		List<StringBuffer> strList = new ArrayList<>(); 
		for (int i = 0; i < Math.min(numRows,s.length());i++){
     
			strList.add(new StringBuffer());
		}
		
		// 声明方向变量,当前行变量
		boolean goDown = false;
		int curRow = 0;
		char[] strChar = s.toCharArray();
		for (int i = 0;i<strChar.length;i++){
     
			strList.get(curRow).append(strChar[i]);
			// 到达两个端点的时候改变方向
			if (curRow == 0 || curRow == numRows - 1){
     
				goDown = !goDown;
			}
			curRow += goDown ? 1 : -1;
		}
		
		// 对numRow个StringBuilder进行合并
		StringBuffer str = new StringBuffer();
		for(StringBuffer sb : strList){
     
			str.append(sb);
		}
		return str.toString();
	}
}

你可能感兴趣的:(LeetCode,java,leetcode)