题目描述
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"
.
题目大意
给一个字符串,判断该字符串是否是一个经过前序序列化之后的二叉树。
(树结点用整数表示,空结点用‘#’表示,分割符为‘,’)
示例
E1
E2
E3
解题思路
用栈来保存结点访问情况,栈中只需保存bool类型,每次遇到两个‘#’类型将栈顶出栈,同时将栈顶的true变为false,若栈顶为false,则代表其左结点以出栈,则将其出栈,直到栈顶为true,并将其改为false。
复杂度分析
时间复杂度:O(N)
空间复杂度:O(N)
代码
class Solution { public: bool isValidSerialization(string preorder) { stack<bool> node; if(preorder == "#") return true; int i; // 遍历字符串 for(i = 0; i < preorder.length(); ++i) { if(preorder[i] == ',') continue; // 若访问到一个空结点 else if(preorder[i] == '#') { // 若栈为空,则说明该树非法,退出循环 if(node.empty()) break; // 若栈顶为true, 将其改为false if(node.top()) { node.pop(); node.push(false); } // 否则需要将栈顶的所有的false出栈 else { node.pop(); if(node.empty()) break; while(!node.empty() && !node.top()) { node.pop(); } if(!node.empty()) { node.pop(); node.push(false); } if(node.empty()) break; } } // 否则代表访问到结点值 else { int j = i + 1; while(j < preorder.length() && preorder[j] != '#' && preorder[j] != ',') ++j; node.push(true); i = j - 1; } } // 若提前退出循环或栈非空,则代表树非法 if(i != preorder.length() - 1 || !node.empty()) return false; return true; } };