LintCode 1066 · Verify Preorder Serialization of a Binary Tree (二叉树判断好题)

发布时间:2024年01月18日

1066 · Verify Preorder Serialization of a Binary Tree
Algorithms
Medium

Description
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
Example 1:
Input: tree = “#”
Output: true

Explanation:
Empty tree is legal.

Example 2:
Input: tree = “9,3,4,#,#,1,#,#,2,#,6,#,#”
Output: true

Example 3:
Input: tree = “1,#”
Output: false

Explanation:
It's not a complete tree.

Example 4:
Input: tree = “9,#,#,1”
Output: false

Explanation:
It's not a tree.

解法1:
helper() 函数里面:

  1. 如果遇到‘#'返回true。
  2. 如果index >= tokens.size(), 返回false。
  3. 否则递归调用左子树和右子树。
    在main()函数里面,如果helper(tokens, 0)返回true还不够,还必须判断当前index是不是等于tokens.size() - 1。否则如果input="#,#"的话, helper(tokens, 0)还是会返回true。
class Solution {
public:
    /**
     * @param preorder: a string
     * @return: return a bool
     */
    bool isValidSerialization(string &preorder) {
        // write your code here
        vector<string> tokens;
        stringstream ss(preorder);
        string token;
        while (getline(ss, token, ',')) {
            tokens.push_back(token);
        }
        int index = 0;
        return helper(tokens, index) && index == tokens.size() - 1;
    }
private:
    bool helper(vector<string> &tokens, int& index) {
        if (index >= tokens.size()) return false;
        if (tokens[index][0] == '#') {
            return true;
        } else {
            return helper(tokens, ++index) && helper(tokens, ++index);
        }
    }
};

解法2:用stringstream。很方便。
注意:因为preorder是用’,'而不是空格隔开的,所以得到下一个token是用getline(ss, token, ‘,’)。如果返回false, 说明ss已经读完。
如果preorder是用空格隔开,则可以简单的用ss >> token得到下个token,其返回值false也是说明ss已经读完。

class Solution {
public:
    /**
     * @param preorder: a string
     * @return: return a bool
     */
    bool isValidSerialization(string &preorder) {
        // write your code here
        vector<string> tokens;
        stringstream ss(preorder);
        string token;
        return helper(ss) && !getline(ss, token, ',');
    }
private:
    bool helper(stringstream &ss) {
        string token;
        if (!getline(ss, token, ',')) return false;
        if (token[0] == '#') {
            return true;
        } else {
            return helper(ss) && helper(ss);
        }
    }
};

解法3:
参考的labuladong的解法。

  1. 一个空节点消耗一个edge,不生成任何edge。
  2. 一个非空节点消耗一个edge, 又生出两个edge。
  3. edgeCount要初始化为0。
  4. 注意:在处理非空节点时,应该先edgeCount–, 判断edgeCount是否<0,再edgeCount++。
    不能简单的就edgeCount += 1。否则case "#,2,#"会返回true。这是不对的。
class Solution {
public:
    /**
     * @param preorder: a string
     * @return: return a bool
     */
    bool isValidSerialization(string &preorder) {
        if (!preorder.empty() && preorder.find(',') == string::npos) return preorder[0] == '#';
        vector<string> tokens;
        stringstream ss(preorder);
        string token = "";
        int edgeCount = 1; //注意,edgeCount要初始化为0。
        
        while (getline(ss, token, ',')) {
            if (token[0] == '#') {
                edgeCount--; //空节点消耗一个edge,不生成任何edge。
                if (edgeCount < 0) return false;
            } else {
                //edgeCount++; 
                edgeCount--; //非空节点消耗一个edge, 又生出两个edge。 注意case "#,2,#"
                if (edgeCount < 0) return false;
                edgeCount += 2;
            }
        }
        return edgeCount == 0;
    }
};
文章来源:https://blog.csdn.net/roufoo/article/details/135663700
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。