圖論應用題 驗證二元樹節點 Validate Binary Tree Nodes_Leetcode #1361

更新於 2024/10/16閱讀時間約 5 分鐘

這題的題目在這裡:

題目敘述

題目會給我們節點總數目n、左子樹的關係陣列、右子樹的關係陣列,要求我們驗證在給定的條件下,能不能構成一顆合法的二元樹。


測試範例

Example 1:

raw-image
Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
Output: true

Example 2:

Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
Output: false

Example 3:

Input: n = 2, leftChild = [1,0], rightChild = [-1,-1]
Output: false



約束條件

Constraints:

  • n == leftChild.length == rightChild.length
  • 1 <= n <= 104
  • -1 <= leftChild[i], rightChild[i] <= n - 1

演算法

先找出根結點,根結點Root不會是別人的子樹,所以根結點Root一定不會出現在leftChild和RightChild這兩個關係陣列。

如果根結點Root找不到,代表樹根不存在,樹根不存在可以提早返回False,代表這不是一顆合法的二元樹。

如果根結點找的到,那接下來就用經典的DFS或者BFS以根結點Root為起始點,拜訪整顆二元樹

假如最後剛好拜訪n個節點,並且沒有重複,那麼就可以驗證這是一顆合法的二元樹。

如果有重複拜訪,代表途中存在環路,二元樹不允許環路Cycle出現,直接返回False,代表這不是一顆合法的二元樹。


程式碼

class Solution:
 def validateBinaryTreeNodes(self, n: int, leftChild: List[int], rightChild: List[int]) -> bool:
  
  # Definition of NULL (i.e., empty node), given by description
  NULL = -1
  
  # --------------------------------------------------------------
  def find_root():
   
   children = set(leftChild) | set(rightChild)

   # search for root node, root node is not a child node always.
   for i in range(n):
    if i not in children:
     return i
   
   return NULL
  
  # --------------------------------------------------------------
  
  root = find_root()
  
  if root == NULL:
   # Reject, because root doesn't exist
   return False
  
  
  
  # launch BFS to given graph
  queue = deque([root])
  visited = set()
  
  while queue:
   
   cur = queue.popleft()
   
   if cur in visited:
    
    # Reject, because there is a cycle
    # Cycle is not allowed in binary tree
    return False
   
   visited.add(cur)
   
   if leftChild[cur] != NULL:
    queue.append( leftChild[cur] )
    
   if rightChild[cur] != NULL:
    queue.append( rightChild[cur] )
  
  
  # BFS in binary tree must visit n nodes exactly, without repetition.
  return len(visited) == n

複雜度分析

時間複雜度: O( n)
定位根結點耗費O(n),拜訪整棵樹也耗費O(n)

空間複雜度: O(n)
演算法中,建立了一個children集合,所佔用記憶體空間為O(n)

BFS拜訪所用到的Queue或者DFS拜訪所用到的Stack,佔用空間最多也為O(n)


關鍵知識點

拜訪二元樹,就想到經典的DFS和者BFS模板。

另外,二元樹裡面,不允許環路Cycle出現。


Reference:

[1] Python O(n) by DFS / BFS / UnionFind [w/ Comment] - Validate Binary Tree Nodes - LeetCode

avatar-img
90會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
題目會給我們兩條已經從小到大排序好的串列,要求我們依照從小到大的順序,合併這兩條串列。
題目的輸入會給我們一個串列,要求我們從頭到尾反轉整個串列。 例子: 如果輸入是1 -> 2 -> 3,那麼輸出就是 3 -> 2 -> 1
題目會給定給我們一顆二元樹的根結點, 要求我們輸出上下顛倒的Level-order traversal的拜訪結果。
題目會給我們一顆二元樹的根節點, 要求我們對齊根節點正中央的虛擬分割線,反轉整顆二元樹。
題目會給定一顆二元樹的根結點,要求我們驗證這一顆樹是否為合法的二元搜索樹, 也就是所謂的Binary search tree, aka BST?
題目會給定給我們一顆二元樹的根結點,要求我們輸出Level-order traversal的拜訪結果。 在這題,我們會複習並利用BFS模板,來實現逐層搜索演算法。
題目會給我們兩條已經從小到大排序好的串列,要求我們依照從小到大的順序,合併這兩條串列。
題目的輸入會給我們一個串列,要求我們從頭到尾反轉整個串列。 例子: 如果輸入是1 -> 2 -> 3,那麼輸出就是 3 -> 2 -> 1
題目會給定給我們一顆二元樹的根結點, 要求我們輸出上下顛倒的Level-order traversal的拜訪結果。
題目會給我們一顆二元樹的根節點, 要求我們對齊根節點正中央的虛擬分割線,反轉整顆二元樹。
題目會給定一顆二元樹的根結點,要求我們驗證這一顆樹是否為合法的二元搜索樹, 也就是所謂的Binary search tree, aka BST?
題目會給定給我們一顆二元樹的根結點,要求我們輸出Level-order traversal的拜訪結果。 在這題,我們會複習並利用BFS模板,來實現逐層搜索演算法。
你可能也想看
Google News 追蹤
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
在檢查列表中含有tuple的座標點時,若要給其他演算法做運算時若有其中有tuple有空值時,就會報錯。 本文主要介紹兩種方法可以檢查是否有空值 程式範例1 positon_list =[(42,123),(None,None),(22,11)] for cord in positon_lis
Thumbnail
前言 如文章的封面圖片1/2~1/27總共有幾天呢? 如果你的答案是25天,那務必把這個日期的地雷搞懂 種樹問題計算 題目 一條路有50公尺,每10公尺種一棵樹,請問總共種了幾顆樹? 這時就會直覺,阿不就是50/10=5,總共種了5顆樹!! 但其實大錯特錯哦❌
藉由是非題的回答情況來反推答案與分數
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
Node 對我來說一直是很似懂非懂的概念,因為沒有實際可見的數字或字串實物可以觀察中間步驟,比起其他解題抽象許多。以下解題方法來自網友與 GPT 提供的答案,我想在本文中嘗試自己做視覺化圖解,說明 CodeWars - Can you get the loop ? 的解題思路。
Thumbnail
「A是B/B在A」主題為讓小朋友了解許多事情與物品像是一串一串的連結,讓孩子們能理解一樣物品背後會有很多連結。 認識柑橘類水果,哪個是柳丁?哪個是
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
在檢查列表中含有tuple的座標點時,若要給其他演算法做運算時若有其中有tuple有空值時,就會報錯。 本文主要介紹兩種方法可以檢查是否有空值 程式範例1 positon_list =[(42,123),(None,None),(22,11)] for cord in positon_lis
Thumbnail
前言 如文章的封面圖片1/2~1/27總共有幾天呢? 如果你的答案是25天,那務必把這個日期的地雷搞懂 種樹問題計算 題目 一條路有50公尺,每10公尺種一棵樹,請問總共種了幾顆樹? 這時就會直覺,阿不就是50/10=5,總共種了5顆樹!! 但其實大錯特錯哦❌
藉由是非題的回答情況來反推答案與分數
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
Node 對我來說一直是很似懂非懂的概念,因為沒有實際可見的數字或字串實物可以觀察中間步驟,比起其他解題抽象許多。以下解題方法來自網友與 GPT 提供的答案,我想在本文中嘗試自己做視覺化圖解,說明 CodeWars - Can you get the loop ? 的解題思路。
Thumbnail
「A是B/B在A」主題為讓小朋友了解許多事情與物品像是一串一串的連結,讓孩子們能理解一樣物品背後會有很多連結。 認識柑橘類水果,哪個是柳丁?哪個是