331. Verify Preorder Serialization of a Binary Tree
方法一:
我自己的方法,建一个stack,每遇到数字就推进栈里,每遇到#,就弹出一个数字,最后栈里必须剩一个#。
1 public boolean isValidSerialization(String preorder) { 2 if(preorder == null || preorder.length() == 0) { 3 return false; 4 } 5 String[] res = preorder.split(","); 6 Stack<String> stack = new Stack<String>(); 7 stack.push(res[res.length - 1]); 8 for(int i = 0; i < res.length - 1; i++) { 9 String each = res[i]; 10 if("#".equals(each)) { 11 if(!stack.isEmpty()) { 12 stack.pop(); 13 } else { 14 return false; 15 } 16 } else { 17 stack.push(each); 18 } 19 } 20 return !stack.isEmpty() && stack.peek().equals("#"); 21 }
时间复杂度是O(n)
2. 别人的方法
每一个数字可以有两条发出的边,每个#会占用一条边,每一个数字自己本身会占用一个边,但是又会产生两个边,所以维持一个计数,一旦小于0就返回false。
注意的是:
1)这个数字初始化是1,相当于,一个根节点自己用掉1条是-1,又产生俩,所以加起来是1;
2)每遇到数字的时候,要把-1和+2分开做,如果-1的时候就小于0了,就返回false
1 public boolean isValidSerialization(String preorder) { 2 String[] res = preorder.split(","); 3 int count = 1; 4 for (String each : res) { 5 if (--count < 0) { 6 return false; 7 } 8 if (!"#".equals(each)) { 9 count += 2; 10 } 11 } 12 return count == 0; 13 }
时间复杂度是O(n)
方法三:
非常好看的方法,每一个叶节点的结构是“数字,#,#”,所以我们把所有的这样的格式都替换成一个“#”,不断地收缩,直到缩到最后应该是一个#。
1 public boolean isValidSerialization(String preorder) { 2 String after = preorder.replaceAll("\\d+,#,#", "#"); 3 return after.equals("#") || !after.equals(preorder) && isValidSerialization(after); 4 }
第三行,之所以有“!after.equals(preorder)”,是因为比如一个不合法的树“1,2,3”,并没有“数字,#,#”这样的结构,所以replaceAll不会改变它
时间复杂度是O(n^2)