解題思路: 因爲葉子節點必定不要安裝監視器,這樣才能使總監視器數量比較少,所以須要從下往上進行判斷當前節點的狀態(共:3種狀態):node
對於空節點,咱們認爲是可觀,但沒有安裝監視器,所以,葉子節點就爲不可觀的了,設想一個節點的左右孩子(爲空)均可觀且沒有安裝監視器,那該節點必然是不可觀即2spa
有了以上對空節點和葉子節點的處理,咱們再來正式分析非終端節點:code
記住,咱們以上的分析都是基於從整個二叉樹的葉子節點往根部,即從下往上進行,並且要作的就是將不可觀的節點變得可觀才行(所以要根據左右孩子的節點的狀態來判斷當前節點狀態並作出調整)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的順序是不能變的,先判斷左右都是不可觀的,再就是均可觀,左或右至少有一個爲監視器,最後纔是均可觀都無監視器.二叉樹