序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #
。
_9_
/ \
3 2
/ \ / \
4 1 # 6
/ \ / \ / \
# # # # # #
例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#"
,其中 #
代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
每个以逗号分隔的字符或为一个整数或为一个表示 null
指针的 '#'
。
你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3"
。
示例 1:
输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
示例 2:
输入: "1,#"
输出: false
示例 3:
输入: "9,#,#,1"
输出: false
解题思路:
利用字符串建立二叉树,查看最后是否有剩余结点,或者中途失败。
- 同样的方法,不建立二叉树,只计算中的出度。
建立二叉树的方法有的数据结构的课本讲到过,有两种方法一种是迭代法,另一种是递归法。
主要介绍下度的计算。
首先要明白下面几点。
字符一共有两种,数字和‘#’
1.加入数字后整个树的出度加1
2.加入'#'出度减1.
累加的过程中,一旦发现整个树的出度小于0是,建立树就失败了。
C++代码
//方法1 class Solution { public: struct TreeNode { string val; TreeNode *left; TreeNode *right; TreeNode(string x) : val(x), left(NULL), right(NULL) {} }; bool isValidSerialization(string preorder) { int size = preorder.size(),i; for (i = 1; i <= size; i++) { if (preorder[i - 1] == ',') preorder[i - 1] = ' '; } stringstream ss; ss << preorder; string sgn; while (ss >> sgn) { data.push_back(sgn); } if (int(data.size()) == 1) return data.back() == "#"; //判断data的先序序列化 return isValid(); } private: bool isValid() { int pos = 0; stack<TreeNode*> S; TreeNode* root=new TreeNode(""), *p = root; while (data[pos] != "#") { p->left = new TreeNode(data[pos++]); S.push(p->left); p = p->left; } while (!S.empty()) { p = S.top(); if (!p->left) { if (pos >= int(data.size())) return false; p->left = new TreeNode(data[pos++]); if (pos >= int(data.size())) return false; p->right = new TreeNode(data[pos++]); p = p->right; if (p->val != "#") { S.push(p); while (data[pos] != "#") { if (pos >= int(data.size())) return false; p->left = new TreeNode(data[pos++]); p = p->left; S.push(p); } } } else if(!p->right){ if (pos >= int(data.size())) return false; p->right = new TreeNode(data[pos++]); if (p->right->val == "#") continue; else { S.push(p->right); p = p->right; while (data[pos] != "#") { if (pos >= int(data.size())) return false; p->left = new TreeNode(data[pos++]); p = p->left; S.push(p); } } } else S.pop(); } return pos == int(data.size()); } vector<string> data; }; |
//方法2 class Solution { public: bool isValidSerialization(string preorder) { if (preorder.empty()) return true; int n = preorder.size(); int s = 1; for (int i = 0; i<n; ++i) { if (preorder[i] == '#') --s, ++i; else { for (; i<n && preorder[i] != ','; ++i); if (s == 0) return false; ++s; } if (s<0) return false; } return s == 0; } }; |