Verify Preorder Serialization of a Binary Tree

来源:互联网 发布:霸王举鼎是真的吗 知乎 编辑:程序博客网 时间:2024/05/01 05:42

题目描述:

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

解题思路:

一棵二叉树的叶子节点数目比内部节点的数目多1,因此可以把给定的字符串划分成两部分,一部分属于左子树,另一部分属于右子树。然后递归的判断两个字符串是否符合子二叉树的先序遍历。

字符串划分的方法:先对输入的字符串进行切分,可以得到一个字符串数组(把"#"当做叶子节点,其他的字符串当做内部节点)。然后从第二个字符串开始遍历字符串数组(因为第一个字符串属于根结点),直到“#”出现的次数比其他字符串的多1,这部分字符串就是属于左子树的部分。然后剩下的部分就是属于右子树。


AC代码如下:

class Solution {public:bool isValidSerialization(string preorder) {if (preorder.size() == 0) return false;vector<string> values = splitString(preorder);int n = values.size();if (n == 1) return values[0] == "#";if (n > 1 && values[0] == "#") return false;return help(values);}bool help(vector<string>& nodes){int n = nodes.size();if (n == 1 || n == 3) return true;int null_node_nums = 0;int inner_node_nums = 0;vector<string> leftTree;vector<string> rightTree;int i = 1;for (; i < n; ++i){if (nodes[i] == "#"){++null_node_nums;if (null_node_nums == inner_node_nums + 1){leftTree = vector<string>(nodes.begin() + 1, nodes.begin() + i + 1);break;}}else{++inner_node_nums;}}if (i >= n) return false;++i;int start = i;null_node_nums = 0;inner_node_nums = 0;for (; i < n; ++i){if (nodes[i] == "#"){++null_node_nums;if (null_node_nums == inner_node_nums + 1){rightTree = vector<string>(nodes.begin() + start, nodes.begin() + i + 1);break;}}else{++inner_node_nums;}}if (i >= n || i!=n-1) return false;return help(leftTree) && help(rightTree);}private:vector<string> splitString(const string& s){vector<string> ans;int len = s.length();if (len == 0) return ans;for (int i = 0; i < len;){int pos = s.find(',', i);if (pos != string::npos){if (pos == i){i = pos + 1;continue;}else{string strTemp = s.substr(i, pos - i);ans.push_back(strTemp);i = pos + 1;}}else{string strTemp = s.substr(i, len - i);ans.push_back(strTemp);break;}}return ans;}};


0 0
原创粉丝点击