Day31 貪心演算法part5

haohaoscnblogs發表於2024-08-16

目錄
  • 任務
    • 56. 合併區間
      • 思路
    • 738. 單調遞增的數字
      • 思路
    • 968. 監控二叉樹
      • 思路

任務

56. 合併區間

以陣列 intervals 表示若干個區間的集合,其中單個區間為 intervals[i] = [starti, endi] 。請你合併所有重疊的區間,並返回 一個不重疊的區間陣列,該陣列需恰好覆蓋輸入中的所有區間 。

思路

按照左區間排序,判斷重疊區間,擴充套件重疊區間(重疊時修改result,不重疊時擴充套件result)。

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        result = []
        intervals.sort(key=lambda x: x[0]) #按照區間左區間排序
        result.append(intervals[0])
        for i in range(1,len(intervals)):
            if intervals[i][0] <= result[-1][1]: #重疊
                result[-1][1] = max(intervals[i][1],result[-1][1])
            else:
                result.append(intervals[i])
        return result

738. 單調遞增的數字

當且僅當每個相鄰位數上的數字 x 和 y 滿足 x <= y 時,我們稱這個整數是單調遞增的。

給定一個整數 n ,返回 小於或等於 n 的最大數字,且數字呈 單調遞增 。

思路

從低位到高位依次比較,不滿足要求時,高位-1,當前高位之後的低位都變成9。

class Solution:
    def monotoneIncreasingDigits(self, n: int) -> int:
        nstr = str(n)
        flag = len(nstr)
        
        for i in range(len(nstr)-2,-1,-1):
            if nstr[i+1] < nstr[i]:
                flag = i+1
                nstr = nstr[:i] + str(int(nstr[i])-1) + nstr[i+1:]
            
        for i in range(flag,len(nstr)):
            nstr = nstr[:i] + '9' + nstr[i+1:]
        
        return int(nstr)

968. 監控二叉樹

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

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

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

思路

節點狀態分為3種情況,0.無覆蓋 1.有攝像頭 2.有覆蓋,遍歷過程中給節點賦予正確的狀態。 當節點是攝像頭狀態時,計數。

  • 為什麼空節點的狀態為2呢,這是因為我們不會在葉子節點放攝像頭,而要在葉子節點的父節點放攝像頭,如果預設空節點狀態為0,則葉子節點必須為1,如果預設空節點狀態為1,則葉子節點的父節點就不能放攝像頭。所以空節點的狀態設為2.
  • 注意根節點的特殊處理,即設定完狀態後,如果根節點的狀態是無覆蓋,則還需要在根節點設定攝像頭。
class Solution:
    def __init__(self) -> None:
        self.result = 0
    def minCameraCover(self, root: Optional[TreeNode]) -> int:
        if self.dfs(root) == 0:
            self.result+=1
        return self.result
        
    def dfs(self,node: Optional[TreeNode]): # 0.無覆蓋 1.有攝像頭 2.有覆蓋
        if not node: return 2
        left = self.dfs(node.left)
        right = self.dfs(node.right)
        
        if left==2 and right==2: #1.左右孩子都有覆蓋
            return 0
        if left==0 or right==0: #2.左右孩子至少有一個無覆蓋
            self.result+=1
            return 1
        if left==1 or right==1: #3.左右孩子至少有一個有攝像頭
            return 2
        return -1     #不會走到這裡    

相關文章