Leetcode 331.验证二叉树的前序序列化

验证二叉树的前序序列化

序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如#

 

例如,上面的二叉树可以被序列化为字符串"9,3,4,#,#,1,#,#,2,#,6,#,#",其中#代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

每个以逗号分隔的字符或为一个整数或为一个表示null指针的'#'

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3"

示例 1:

输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"

输出: true

示例 2:

输入: "1,#"

输出: false

示例 3:

输入: "9,#,#,1"

输出: false

 

 

要求在不重建树的情况下,判断一个字符串是否为某树的先序遍历序列。

使用递归求解。

若一个序列只有一个"#",显然这是正确的。

若一个序列的第一个元素不是"#",那么一个合法的序列一定可以分成三部分来看待:根(第一个元素),左子树(从第二个元素开始算起到第x个元素),右子树(从第x+1个元素算起到序列末尾)。因此,跳过第一个元素(根)后,我们在从第二个元素开始的子序列中,先尝试找到一棵完整的树(左子树),如果找不到,那么显然是不合法的。如果找到了,那么我们再从这棵完整的树后面开始,尝试找另一棵树(右子树),如果找不到,那么显然是不合法的。

从第一个元素开始,如果找到了一个完整的树,且长度和序列长度一致,那么就是合法的,否则就是非法的。

  • 空间复杂度:O(1)(注意,为了简便,我下面的代码因为用了一个数组放置从字符串中分离出来的序列,事实上是O(n),但其实这是可以省略的,并非算法本质)
  • 时间复杂度:O(n)

 

 1 public class Solution {
 2     public boolean isValidSerialization(String preorder) {
 3         String[] x = preorder.split(",");
 4         if (findTree(x, 0) == x.length) {
 5             return true;
 6         }
 7         return false;
 8     }
 9     private int findTree(String[] preorder, int start) {
10         if (preorder.length - start == 0) {
11             return -1;
12         }
13         if (preorder[start].equals("#")) {
14             return start + 1;
15         }
16         int left = findTree(preorder, start + 1);
17         if (left < 0) {
18             return -1;
19         }
20         int right = findTree(preorder, left);
21         if (right < 0) {
22             return -1;
23         }
24         return right;
25     }
26 }

 

posted on 2019-01-07 19:40  kexinxin  阅读(578)  评论(0编辑  收藏  举报

导航