【栈】【leetcode】【中等】331. 验证二叉树的前序序列化

题目:

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


例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。

来源:

331. 验证二叉树的前序序列化

解题思路1:栈

读完题后有点懵,仔细看了看题中的例子发现,#都是叶子节点,数字都是非叶节点。

确定思路如下:#出栈,数字入栈

定义一个栈,存储数字节点的孩子个数,数字节点必须有2个孩子。循环所有节点:

  • 当节点是#号时,若栈为空则结束,否则给栈顶元素增加一个孩子;
  • 当节点是数字时,若栈为空则直接入栈,否则给栈顶元素增加一个孩子后再入栈;
  • 当栈顶节点已满足2个孩子时,出栈直到空或栈顶节点不够2个孩子。

当栈为空并且后面没有节点时,返回true,其他false。

代码如下(有点混乱):

class Solution {
public:
    bool isValidSerialization(string preorder) {
        stack<int> st;
        int i = 0;
        while (i < preorder.size()) {
            char ch = preorder[i];
            while (i < preorder.size() && preorder[i] != ',') i++;
            i++;

            if (ch == '#') {
                if (st.empty()) break;
                // top++
                int t = st.top();
                st.pop();
                st.push(t+1);
            } else {
                // top++
                if (!st.empty()) {
                    int t = st.top();
                    st.pop();
                    st.push(t+1);
                }
                st.push(0);
            }
            bool end = false;
            while (st.top() == 2) {
                st.pop();
                if (st.empty()) {
                    end = true;
                    break;
                }
            }
            if (end) break;
        }
        return st.empty() && i >= preorder.size();
    }
};

解题思路2:利用节点性质

每个非叶节点必然有2个孩子,那么一定满足:叶子节点一定比非叶节点多1个。在此题中,则为#节点比数字节点多1个。

根据这个性质写代码就简单了:定义计数cnt=1,当#时--,数字时++,计数0时退出,退出后判断后续还有没有节点。

int isValidSerialization(char * preorder){
    int cnt = 1;
    char *p = preorder;
    while (*p != 0) {
        if (*p == '#') {
            cnt--;
        } else {
            cnt++;
        }
        while (*p != 0 && *p != ',') p++;
        if (*p == ',') p++;

        if (cnt == 0) break;
    }

    return cnt == 0 && *p == 0;
}

猜你喜欢

转载自blog.csdn.net/hbuxiaoshe/article/details/114695571