狀態dfs搜尋 968 監控二叉樹

2022-07-18 12:33:12 字數 1938 閱讀 1393

參考題解:官方題解)

原題:

給定乙個二叉樹,我們在樹的節點上安裝攝像頭。

節點上的每個攝影頭都可以監視其父物件、自身及其直接子物件。

計算監控樹的所有節點所需的最小攝像頭數量。

輸入:[0,0,null,0,0]

輸出:1

解釋:一台攝像頭足以監控所有節點。

輸入:[0,0,null,0,null,0,null,null,0]

輸出:2

解釋:需要至少兩個攝像頭來監視樹的所有節點。

狀態 a:root 必須放置攝像頭的情況下,覆蓋整棵樹需要的攝像頭數目。

狀態 b:覆蓋整棵樹需要的攝像頭數目,無論 root 是否放置攝像頭。

狀態 c:覆蓋兩棵子樹需要的攝像頭數目,無論節點root 本身是否被監控到。

對於狀態a,

root已經放置了攝像頭,那麼root的左兒子和右兒子可以有監控也可以沒有監控。所以如果需要覆蓋整個樹,root已經有了攝像頭情況下(root和root的左兒子右兒子都被監控了),需要求的是對於左兒子和右兒子各自的子樹被完全覆蓋情況下需要的攝像頭數,也就是兒子作為root後的狀態c。所以a的值為1(root上的攝像頭數)+lc+rc

對於狀態b,

假如root放置了攝像頭,等同於a;

假如root沒有放置攝像頭,如果root需要被監控到,那麼左兒子和右兒子中至少有乙個需要裝上攝像頭

所以有三種情況

1.左兒子裝攝像頭,右兒子沒有裝:此時左兒子作為新root需要的攝像頭數是新root必須放置攝像頭的數量,右兒子作為新root不用裝攝像頭但是要被覆蓋的數量。

2.右兒子裝攝像頭,左兒子沒有裝:類似於1

3.左右兒子都裝了攝像頭:兩個兒子都需要放置攝像頭情況下的覆蓋數量。即a+b

由abc定義可以知道,求三種情況的最小值可以這樣: min(la+rb, lb+ra);

la+rb實際為 左兒子有攝像頭右兒子沒有攝像頭 和 左兒子和右兒子都有攝像頭的兩種情況的最小值

lb+ra類似於上

所以最後的狀態b=min(a, min(la+rb, lb+ra));

對於狀態c

如果root裝了攝像頭,覆蓋root的兩個子樹也就等同於a

如果root沒有裝攝像頭,可以把root的兩個子數從root中獨立出來,也就是lb+rb

其實也可以按照root是否被監控來看,如果root被監控,覆蓋root的兩個子樹也就等同於b,沒有被監控同上。

所以c=min(a, lb+rb);或者c=min(b,lb+rb);

**

1/**

2* definition for a binary tree node.

3* struct treenode

8* };9*/

10class

solution

15 status(int a, int b, int

c):a(a), b(b), c(c){}

16}status;

17 status dfs(treenode*root)

21 status l=dfs(root->left);

22 status r=dfs(root->right);

2324

int a=1+l.c+r.c;

25int b=min(a, min(l.a+r.b, l.b+r.a));

26int c=min(b, l.b+r.b);

27return

status(a,b,c);28}

2930

int mincameracover(treenode*root)

34 };

968 監控二叉樹

給定乙個二叉樹,我們在樹的節點上安裝攝像頭。節點上的每個攝影頭都可以監視其父物件 自身及其直接子物件。計算監控樹的所有節點所需的最小攝像頭數量。明確每個節點存在的狀態,當前節點只能存在三種狀態,0為未監控,1為已監控,2為安裝攝像頭,後序遍歷樹,先獲得左右節點的狀態資訊,根據左右節點的狀態資訊來設定...

968 監控二叉樹

關於樹的問題我們一般使用遞迴來解決。首先可以遍歷到樹的最底端 此節點的左右孩子都為空,空孩子標記為狀態1 標記此節點為已覆蓋 狀態0 如果乙個節點的其中乙個左右節點狀態為已覆蓋 即還未安裝監視器 那麼給此節點安裝監視器,並且記錄監視器數量的全域性變數自增。安裝監視器後,給節點標記狀態為2,那麼它的父...

968 監控二叉樹

貪心演算法 自底向上,每三層乙個攝像機,就能使得所用的攝像機最少。對最後乙個根節點做特判ans private int ans 0 public intmincameracover treenode root if dfs root 2 return ans 1 該節點沒設定攝像,但被監控。2 該節...