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
Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.
Analysis:
We use a recursion function to verify whether subtree starting at @start is a valid binary tree or how far it can go to maintain a valid binary tree. This includes a vlid left subtree starting from @start+1 and a valid right subtree staring from @leftEnd+1.
Solution:
1 public class Solution { 2 public boolean isValidSerialization(String preorder) { 3 String[] s = preorder.split(","); 4 5 int res = isValidRecur(0, s); 6 // This condition after completing recursion is IMPORTANT! 7 // Either we found a false subtree, or we ended before going through the 8 // whole string. 9 // NOTE: it is (res+1) rather (res) 10 if (res == -1 || res + 1 < s.length) 11 return false; 12 return true; 13 } 14 15 public int isValidRecur(int start, String[] preorder) { 16 if (start >= preorder.length) 17 return -1; 18 if (preorder[start].equals("#")) 19 return start; 20 21 int leftEnd = isValidRecur(start + 1, preorder); 22 if (leftEnd == -1) 23 return leftEnd; 24 int rightEnd = isValidRecur(leftEnd + 1, preorder); 25 if (rightEnd == -1) 26 return rightEnd; 27 28 return rightEnd; 29 } 30 31 }