研究其走向,发现,可以构建一个StringBuilder对象数组,用来存每行的值,(python,c++中可以建多个char数组),然后在zigzag的斜向边中所对应的StringBuilder数组下标可以用Hashmap存储(python的dict)得到。
import java.util.*; public class ZigzagConversion6 { public String convert(String s, int numRows) { if(numRows==1) return s; StringBuilder[] sb = new StringBuilder[numRows]; Map<Integer,Integer> map = new HashMap<>(); for(int i=0;i<2*numRows-2;i++) { if(i<numRows) map.put(i, i); else map.put(i, 2*numRows-2-i); } for(int i=0;i<numRows;i++) sb[i]=new StringBuilder(); for(int i=0;i<s.length();i++) { int j = i%(2*numRows-2); sb[map.get(j)].append(s.charAt(i)); } StringBuilder res = new StringBuilder(); for(int i=0;i<numRows;i++) { res.append(sb[i]); } return res.toString(); } }
时间复杂度O(n),空间复杂度O(n)。69ms,19,97%。第二遍跑30ms,83.07%。按复杂度看,应该是可以的。
学习22ms答案,优化下边际情况,22ms答案大体思路和我一样,不过实现细节不同,它直接在输出的char数组上操作,以输出数组为导向,而我是以输入字符串为导向的。它可以省去Hashmap等不必要的数据结构,在空间复杂度上更优,时间上也更快,时间复杂度倒是基本一致:
class Solution { public String convert(String s, int numRows) { if(numRows==1||s.length()<=1) return s; char[] schar = s.toCharArray(); char[] output = new char[s.length()]; int outputindex = 0; for(int offset=0;offset<numRows;offset++) { int index = offset; if(index>=s.length()) break; output[outputindex++] = schar[index]; while(index<s.length()) { //skip the last row if(offset<numRows-1) { index+=2*(numRows-1-offset); if(index>=s.length()) break; output[outputindex++] = schar[index]; } //skip the first row if(offset>0) { index+=2*offset; if(index>=s.length()) break; output[outputindex++] = schar[index]; } } } return new String(output); } }
18ms,100%。33ms,73.20%。