LeetCode Verify Preorder Serialization of a Binary Tree

原题链接在这里:https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/

题目:

One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #.

     _9_
    /   \
   3     2
  / \   / \
 4   1  #  6
/ \ / \   / \
# # # #   # #

For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node.

Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree.

Each comma separated value in the string must be either an integer or a character '#' representing null pointer.

You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3".

Example 1:
"9,3,4,#,#,1,#,#,2,#,6,#,#"
Return true

Example 2:
"1,#"
Return false

Example 3:
"9,#,#,1"
Return false

题解:

类似Serialize and Deserialize Binary Tree.

Method 1计算indegree和outdegree是否相加为0, 没遇到一个string, 就是遇到了一个节点, indegree++. root没有indegree, 但会算一遍outdegree, 为了补偿root. inDegree初始化为-1.

每当遇到一个非叶子节点, 就说明它必须有两个孩子. 就是有两个outDegree, 对应的inDegree就减掉2.

最后看inDegree是否为0.

Time Complexity: O(n). Space: O(n).

Method 2 利用stack来表示层级. 两种情况,一是遇到数字, push into stack.

一是#, 看栈顶是不是#, 若是,就一直pop, 每次pop不来两个, 直到不再是#,最后把当前的#再压入stack; 若不是#就 push into stack.

举例

   _1_
    /   \
   3     2
  / \   / \
 #   # #   #

压栈1, 压栈3, 压栈3的左侧叶子节点#. 当遇到3的右侧叶子节点时, pop出来两个, stack顶部变成1, 再把当前叶子节点压入stack中,stack现在有1, #.

就相当于

   _1_
    /   \
   #     2
       / \
      #   #

以此类推,看最后stack的size是不是1, 并且唯一的保留就是#.

Time Complexity: O(n). Space: O(n). String array 大小 O(n), stack 大小O(logn).

AC Java:

 1 public class Solution {
 2     public boolean isValidSerialization(String preorder) {
 3         if(preorder == null || preorder.length() == 0){
 4             return true;
 5         }
 6         
 7         //Method 1, 算indegree 和 outdegree是否相加为0
 8         String [] strArr = preorder.split(",");
 9         int inDegree = -1; //根节点没有indegree, 但下面又算了一遍outdegree, 为了补偿初始inDegree 为-1
10         for(String str : strArr){
11             inDegree++; //没遇到一个str, 说明有一个node, 那么久有一个indegree
12             if(inDegree > 0){
13                 return false;
14             }
15             if(!str.equals("#")){ //但凡非叶子节点,都有two children, outdegree就会多两个, 对比indegree就少两个.
16                 inDegree-=2;
17             }
18         }
19         return inDegree == 0;
20         
21         /*
22         //Method 2, 利用stack
23         Stack<String> stk = new Stack<String>();
24         String [] strArr = preorder.split(",");
25         for(String str : strArr){
26             //若此时stack顶是#, 说明该返回上一层, pop两次, 若顶部又是#, 说明再返回一层, 又pop两次
27             while(str.equals("#") && !stk.isEmpty() && stk.peek().equals("#")){
28                 stk.pop();
29                 if(stk.isEmpty()){ //pop了一个#, stack就空了, 说明没有parent节点, return false
30                     return false;
31                 }
32                 stk.pop(); //一次pop出来两个
33             }
34             stk.push(str); //不论当前的str是什么,最后都压入stack中
35         }
36         return stk.size() == 1 && stk.peek().equals("#");
37         */
38     }
39 }

posted @ 2016-03-21 10:44  Dylan_Java_NYC  阅读(305)  评论(0编辑  收藏  举报