LeetCode – Verify Preorder Serialization of a Binary Tree (Java)

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.

Java Solution

We can keep trimming the leaves until there is no one to remove. If a sequence is like "4 # #", change it to "#" and continue. A stack is a good date structure for this purpose.

Here is an example:
verify-preorder-serialization-of-a-binary-tree-leetcode-java

public boolean isValidSerialization(String preorder) {
    LinkedList<String> stack = new LinkedList<String>();
    String[] arr = preorder.split(",");
 
    for(int i=0; i<arr.length; i++){
        stack.add(arr[i]);
 
        while(stack.size()>=3 
            && stack.get(stack.size()-1).equals("#")
            && stack.get(stack.size()-2).equals("#")
            && !stack.get(stack.size()-3).equals("#")){
 
            stack.remove(stack.size()-1);
            stack.remove(stack.size()-1);
            stack.remove(stack.size()-1);
 
            stack.add("#");
        }
 
    }
 
    if(stack.size()==1 && stack.get(0).equals("#"))
        return true;
    else
        return false;
}

If only stack operations are allowed, the solution can be written in the following way:

public boolean isValidSerialization(String preorder) {
    String[] arr = preorder.split(",");
 
    Stack<String> stack = new Stack<>();
    for(String s: arr){
        if(stack.isEmpty() || !s.equals("#")){
            stack.push(s);
        }else{
            while(!stack.isEmpty() && stack.peek().equals("#")){
                stack.pop();
                if(stack.isEmpty()){
                    return false;
                }else{
                    stack.pop();
                }
            }
            stack.push("#");
        }            
    }
 
    return stack.size()==1 && stack.peek().equals("#");
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • p.andrey

    Oh, yes.. my bad…

  • Pankaj

    This code will return true for this input [9,3,#,#,#]. Different values of diff will be : (0,+2,+3,+2,+1,0) => 0(true)

  • p.andrey

    Try this one: [9,3,#,#,#], per your code is [0, +2, -1, -1, -1] = – 1 => fails, however the tree and the serialization are correct: [(root = 9): left = 3, right = #], [(node = 3): left = #, right = #]. If you move the [node=3] from the left side to the right side you get a fail again.

  • Pankaj

    There is a better solution to this problem. For every non null node there is 2 out degrees and one in degree except root and for every leaf node there is one in-degree. So if we calculate the diff in degrees it shoud be zero for a valid preorder serialization. Code below:


    public boolean isValidSerialization(String preorder) {
    if(preorder == null || preorder.length() <= 0){
    return true;
    }
    String [] nodes = preorder.split(",");
    int diff = 1;
    for (String node : nodes){
    diff--;
    if(diff < 0) return false;

    if(!node.equals("#")) diff+= 2;
    }
    return diff == 0;
    }

  • Nada Abo ElSeod

    The code above won’t work in case of “A, B, #, #, #” which is a valid serialization of a root node A with a left child B.

  • navin

    code is incorrect:
    breaks for the case 9,3,4,#,2,#,#,1,#,#,6,8,#,#,#

  • Rohit

    code is wrong

    93###.stops here

  • Iram22


    private static boolean verify(String s){
    String arr[]=s.split(",");
    Stack stack=new Stack();
    if(arr.length==0 || arr[0]=="#") return true;
    stack.push(0);
    for(int i=1;i<arr.length;i++){
    if(stack.size()==0) return false;
    if(i!=stack.peek()+1){ stack.pop();}
    if(arr[i].equals("#")){ continue;}
    stack.push(i);
    }
    if(stack.size()!=0) return false;
    return true;
    }

  • Matias SM

    Alternate solution:

    boolean isValidPreorder(String serialization) {
    String[] nodes = serialization.split(",");
    return isValidPreorder(nodes, 0) == nodes.length;
    }

    int isValidPreorder(String[] nodes, int startIdx) {
    if (startIdx >= nodes.length) return -1;

    //end node
    if (nodes[startIdx].equals("#")) return startIdx + 1;

    //left branch
    int nextIdx = isValidPreorder(nodes, startIdx + 1);

    //right branch (note that it must exists to be a valid in order)
    return nextIdx != -1? isValidPreorder(nodes, nextIdx) : -1;
    }

    Disclaimer: I don’t think I’m breaking the condition of “not reconstruct the tree” since I’m not doing it per-se.

  • Sonam Gupta

    this code is wrong.