下面是我在LeetCode中看到的题目,然后自己写的解决方法
/**
* Z字型变化
* 原字符串“LEETCODEISHIRING”
* after->
* L C I R
* E T O E S I I G
* E D H N
* 然后输出“LCIRETOESIIGEDHN”
*/
public String convert(String s, int numRows) {
if(numRows < 2) return s;//小于两行无法进行变换
int unitCount = 2 * numRows - 2;//表示一个变换单元中最大的字符量
String[] rows = new String[numRows];//保存转换格式后每一行的子字符串
Arrays.fill(rows,"");
for (int i = 0; i < s.length(); i++) {
int t;
if (i+1 <= unitCount){
t = i + 1;
} else {
t = (i + 1) % unitCount;
}
t = t == 0 ? unitCount : t;
if(t > numRows){
t = numRows - (t - numRows);
}
rows[t-1] += String.valueOf(s.charAt(i));
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < rows.length; i++) {
sb.append(rows[i]);
}
return sb.toString();
}
必须承认我的解题方法写的比较复杂,也很晦涩。。。主要是新建一个数组,用于保存变换后的每行字符,因此数组的长度就等于Z字变换的numRows。
然后这是我在LeetCode上看到有其它大佬写的,更加简洁,效率也更高的算法
public String convert(String s, int numRows) {
if(numRows < 2) return s;
List<StringBuilder> rows = new ArrayList<StringBuilder>();
for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());
int i = 0, flag = -1;
for(char c : s.toCharArray()) {
rows.get(i).append(c);
if(i == 0 || i == numRows -1) flag = - flag;
i += flag;
}
StringBuilder res = new StringBuilder();
for(StringBuilder row : rows) res.append(row);
return res.toString();
}
//作者:jyd
//链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/zzi-xing-bian-huan-by-jyd/
这个算法巧妙地利用了flag,以及使用List + StringBuilder代替了数组+String,这样的效率是非常高的。