一个街区为了提高街区安全性,需要在街区的路灯上安装若干摄像头,用一个二叉树表示街区的路灯。 每个节点表示一个路灯,在路灯上安装摄像头。每个摄像头可以监控其自身、父对象和直接子对象。 为保证每个路灯都被监控,请计算所需的最小摄像头数。

输入描述:

输入一串字符,代表由前序排列的二叉树表示的路灯,字符由'0'和'#'组成,每个'0'表示一个要监控的路灯, '#'表示子节点为空

输出描述:

所需最小摄像头数。

思路

构建二叉树采用消融的方式:将'0##'变成一个‘#’放回字符串。重复这个方式直到 字符串只剩下一个‘#’,树就建成了。

建树的过程实际上是一个递归返回的过程,和我们递归遍历一棵树是等价的。 因此,可以把求解的过程和建树一同进行。每找到一棵树[既0##]:

1. 确定子树放的路灯数量;
2.确定子树需不需要父节点帮忙放路灯
3.确定子树的根有没有放路灯,从而决定自己需不需要放。
 struct TreeNode {
      char val;
      char tag;
      bool need;
      bool put;
      size_t count;
      TreeNode *left, *right;
      TreeNode(char x) : val(x), tag(x), 
                left(NULL), right(NULL),
                need(false), put(false), count(0){}
};

void delTree(TreeNode* root){
    queue<TreeNode*> fifo;
    fifo.push(root);
    while(!fifo.empty()){
        TreeNode* node = fifo.front();
        if(node){
            fifo.push(node->left);
            fifo.push(node->right);
            delete node;
        }
        fifo.pop();
    }
}

size_t makeTree(string s){
    stack<TreeNode*> st;
    for(int i = 0; i < s.size();++i){
        if(!st.empty() && (s[i] == '#' && st.top()->tag == '#')){
            TreeNode* r = new TreeNode('#');
            while(!st.empty() && st.top()->tag == '#'){
                TreeNode* l = st.top();
                st.pop();
                TreeNode* root = st.top();
                st.pop();
                root->left = l;
                root->right = r;
                root->tag = '#';

                root->count += l->count;
                root->count += r->count;

                if(l->need || r->need){
                    root->count += 1;
                    root->put = true;
                    root->need = false;
                }else if(l->put || r->put){
                    root->need = false;
                    root->put = false;
                }else{
                    root->put = false;
                    root->need = true;
                }
                r = root;
            }
            st.push(r);
        }else{
            st.push(new TreeNode(s[i]));
        }
    }
    auto root =  st.top();
    size_t result = root->need ? root->count + 1 : root->count;
    delTree(root);
    return result;
}