[LeetCode] 968. Binary Tree Cameras 二叉樹相機



Given a binary tree, we install cameras on the nodes of the tree.

Each camera at a node can monitor its parent, itself, and its immediate children.

Calculate the minimum number of cameras needed to monitor all nodes of the tree.

Example 1:

Input: [0,0,null,0,0]
Output: 1
Explanation: One camera is enough to monitor all nodes if placed as shown.

Example 2:

Input: [0,0,null,0,null,0,null,null,0]
Output: 2
Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.

Note:

  1. The number of nodes in the given tree will be in the range [1, 1000].
  2. Every node has value 0.

這道題給了一棵二叉樹,說是可以在結點上放相機,可以拍父結點,自身,和左右子結點,現在問我們最少需要多少個相機才能拍到所有的結點。由於是一道 Hard 題目,博主下意識的看了一下 Related Topics,發現是 DP。於是博主就開始思考如何定義 dp,並且思考狀態轉移方程。但是沒有想出可行的解法,於是去論壇上逛了一下,發現大家用的都是貪婪算法 Greedy Algorithm,看來博主被 Topics 誤導了。不過不要緊,重要的是跟着大神 lee215 一起來解題吧。這里先來考慮,到底把相機放在什么位置可以拍到最多的結點?是葉結點嗎?不一定是,因為若放在葉結點,只能拍到該葉結點和其父結點兩個而已。是根結點嗎?也不一定,因為放在根結點,最多拍到根結點和其左右兩個子結點,總共三個而已。最優解是放在葉結點的父結點上,這樣最多可以拍到四個結點。所以策略應該是先找到葉結點,讓后在其父結點放上相機,同時標記父結點的父結點為被拍到了。這樣就有3種不同的狀態,用0來表示當前結點是葉結點,1表示當前結點是葉結點的父結點,並被放置了相機,2表示當前結點的是葉結點的爺爺結點,並被相機拍到了。這里使用一個子函數,將全局變量 res 傳進去,用來記錄放置的相機的總個數。在遞歸函數中,若當前結點不存在,則返回2,空結點也可看作已經被相機拍到了。否則分別對左右子結點調用遞歸函數,若二者中有一個返回0了,當前結點至少有一個子結點是葉結點,需要在當前位置放一個相機,結果 res 自增1,並返回1。否則若左右子結點的返回值有一個為1,說明左右子結點中至少有一個已經被放上了相機,當前結點已經被拍到了,返回2。若都不是,則說明當前結點是葉結點,返回0。在主函數中,若對根結點調用遞歸的返回值是0,說明根結點是葉結點,此時沒有辦法,只能在葉結點上放個相機了,所以要加上1,否則不用加,參見代碼如下:


class Solution {
public:
    int minCameraCover(TreeNode* root) {
        int res = 0;
        return (helper(root, res) < 1 ? 1 : 0) + res;
    }
    // Return 0 if leaf, 1 if parent of leaf with camera on this node, 2 if covered without camera on this node.
    int helper(TreeNode* node, int& res) {
        if (!node) return 2;
        int left = helper(node->left, res), right = helper(node->right, res);
        if (left == 0 || right == 0) {
            ++res;
            return 1;
        }
        return (left == 1 || right == 1) ? 2 : 0;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/968


類似題目:

Distribute Coins in Binary Tree


參考資料:

https://leetcode.com/problems/binary-tree-cameras/

https://leetcode.com/problems/binary-tree-cameras/discuss/211180/JavaC%2B%2BPython-Greedy-DFS

https://leetcode.com/problems/binary-tree-cameras/discuss/211966/Super-Clean-Java-solution-beat-100-DFS-O(n)-time-complexity


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM