Leetcode:验证二叉树的前序遍历

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

     _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. 利用字符串建立二叉树,查看最后是否有剩余结点,或者中途失败。
  2. 同样的方法,不建立二叉树,只计算中的出度。

建立二叉树的方法有的数据结构的课本讲到过,有两种方法一种是迭代法,另一种是递归法。

主要介绍下度的计算。

首先要明白下面几点。

字符一共有两种,数字和‘#’

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;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_23523409/article/details/84660068