思路
最初我想用数学方法推倒出来,但是发现还是有点麻烦的,所以果断选择模拟转换过程。
其实过程很简单,就是新建n个Vector,按 1 ~ n 的顺序向Vector末尾添加元素,再按n - 1 ~ 2 的顺序向Vector末尾添加元素。反复直到遍历完字符串。
最后把1 ~ n 个向量拼接成字符串就可以了。
时间复杂度分析
一趟遍历完字符串,所以为O(n)
(直到我看到官方解答用StringBuilder作为每一行元素,我才知道自己有多low)
public static String convert(String s, int numRows){
Vector<Vector<Character>> a = new Vector<>();
for (int i = 0; i < numRows ; i++) {
a.add(new Vector<>());
}
int pointer = 0;
boolean flag = true;
while (flag){
for (int i = 0; i < numRows ; i++, pointer ++) {
if(pointer >= s.length()){
flag = false;
break;
}
a.get(i).add(s.charAt(pointer));
}
for (int i = numRows - 2; i >= 1 ; i --, pointer ++) {
if(pointer >= s.length()){
flag = false;
break;
}
a.get(i).add(s.charAt(pointer));
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i <numRows ; i++) {
for (int j = 0; j < a.get(i).size() ; j++) {
sb.append(a.get(i).get(j));
}
}
return sb.toString();
}
修改后代码
(注意一开始不用数组是因为Java不能创建泛型数组,Vector<Character>[] a = new Vector<Character>[numRows]编译通不过)
public static String convert(String s, int numRows){
StringBuilder[] a = new StringBuilder[numRows];
for (int i = 0; i < numRows; i++) {
a[i] = new StringBuilder();
}
int pointer = 0;
boolean flag = true;
while (flag){
for (int i = 0; i < numRows ; i++, pointer ++) {
if(pointer >= s.length()){
flag = false;
break;
}
a[i].append(s.charAt(pointer));
}
for (int i = numRows - 2; i >= 1 ; i --, pointer ++) {
if(pointer >= s.length()){
flag = false;
break;
}
a[i].append(s.charAt(pointer));
}
}
StringBuilder sb = new StringBuilder();
for (StringBuilder x:
a) {
sb.append(x.toString());
}
return sb.toString();
}