【leetcode 968. 監控二叉樹】解題報告

解題思路: 因爲葉子節點必定不要安裝監視器,這樣才能使總監視器數量比較少,所以須要從下往上進行判斷當前節點的狀態(共:3種狀態):node

  • 0: 當前節點安裝了監視器
  • 1: 當前節點可觀,但沒有安裝監視器
  • 2: 當前節點不可觀

對於空節點,咱們認爲是可觀,但沒有安裝監視器,所以,葉子節點就爲不可觀的了,設想一個節點的左右孩子(爲空)均可觀且沒有安裝監視器,那該節點必然是不可觀即2spa

有了以上對空節點和葉子節點的處理,咱們再來正式分析非終端節點:code

  • 若一個節點的左孩子或右孩子不可觀,那麼該節點必然不可觀,須要安裝監視器,所以返回0狀態
  • 若一個節點的左孩子或右孩子均可觀且至少有一個安裝了監視器,那麼該節點必然是可觀的,返回1狀態
  • 若一個節點的左右孩子均可觀且沒安裝監視器,那麼該節點必然是不可觀的,返回2狀態

記住,咱們以上的分析都是基於從整個二叉樹的葉子節點往根部,即從下往上進行,並且要作的就是將不可觀的節點變得可觀才行(所以要根據左右孩子的節點的狀態來判斷當前節點狀態並作出調整)blog

這裏可能會有疑惑,以上的第一條得出當前節點不可觀,而後安裝了監視器,而第三條也得出當前節點不可觀,但卻沒有安裝監視器,而是直接返回的2狀態(當前節點不可觀).這是爲何?遞歸

由於,對於第一條,由於左右孩子都不可觀,爲了讓左右孩子均可觀,則必須給當前節點安裝監視器才行,而第三條中,左右孩子都是可觀的(沒有安裝監視器),當前節點的能夠直接返回不可觀狀態,由於後面能夠由他的父節點進行攝像頭安裝,使其變得可觀.it

方法一:遞歸class

    // 0:該節點安裝了監視器 1:該節點可觀,但沒有安裝監視器 2:該節點不可觀
    int monitor = 0;
    int state(TreeNode* node)
    {
        if (node == nullptr) return 1;
        int left  = state(node->left);
        int right = state(node->right);
        // 該節點爲0的狀況
        if (left == 2 || right == 2)
        {
            monitor++;  // 因爲左或右節點不可觀,則須要給當前節點安裝監視器,爲0狀態
            return 0;
        } // 爲1的狀況
        else if (left == 0 || right == 0)
            return 1;   // 當(left!=2&&right!=2)時,纔會進行該判斷,也就是左右節點必定是可觀的,再判斷是否有一個安裝了監視器,若有安裝,則當前節點就不須要安裝監視器也可觀了,爲1狀態
        // 爲2的狀況
        else    // 其餘:黨(left!=2&&right!=2)&&(left!=0&&right!=0),即left==1&&right==1時,左右節點均可觀,但沒有監視器,當前節點不可觀,爲2狀態
            return 2;
    }
    int minCameraCover(TreeNode *root)
    {
        if (root == nullptr) return 0;
        if (state(root) == 2) monitor++;    // 若是根節點爲2的狀態,須要加一個監視器
        return monitor;
    }

 注意:這裏的if,else if,else的順序是不能變的,先判斷左右都是不可觀的,再就是均可觀,左或右至少有一個爲監視器,最後纔是均可觀都無監視器.二叉樹

相關文章
相關標籤/搜索