DFS經典應用題 BST最靠近的公共祖先節點 Leetcode #235

閱讀時間約 3 分鐘

題目敘述

題目會給定我們一顆二元搜索樹的根結點root,和任意兩個樹中的節點p和q。

要求我們找出p, q最靠近的公共祖先節點。

最靠近的公共祖先節點白話講,就是p, q 分別往上走第一個產生交會的節點

題目的原文敘述


測試範例

Example 1:

raw-image
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.

Example 2:

raw-image
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

Example 3:

Input: root = [2,1], p = 2, q = 1
Output: 2
 

約束條件

Constraints:

  • The number of nodes in the tree is in the range [2, 10^5].
  • -109 <= Node.val <= 10^9
  • All Node.val are unique.
  • p != q
  • p and q will exist in the BST.

演算法

善加利用BST的先天規定與特質:

BST本身是一個排序好的二元樹。

左子樹一定比根節點的值還小

右子樹一定比根結點的值還大


討論可能出現的情況:

若p, q 都比根結點,則搜尋左子樹

若p, q 都比根結點,則搜尋右子樹

若p, q一個比根結點大,另一個比根結點小,則當下的節點就是最靠近的公共祖先節點,(Lowest common ancestor, aka LCA )恰好符合定義,即為所求。


程式碼

class Solution:
 def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':

  cur_value = root.val
  
  if p.val > cur_value and q.val > cur_value:
   return self.lowestCommonAncestor( root.right, p, q)
  
  elif p.val < cur_value and q.val < cur_value:
   return self.lowestCommonAncestor( root.left, p, q)
  
  else:
   return root

關鍵知識點

記得聯想到BST二元搜索樹的先天規定與特質:

BST本身是一個排序好的二元樹。

左子樹一定比根節點的值還小

右子樹一定比根結點的值還大


題目的定義,往往就暗藏解題的線索唷!


Reference:

[1] Lowest Common Ancestor of a Binary Search Tree - LeetCode

avatar-img
90會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
題目敘述 題目會給我們一個不規則排列的二維陣列,要求我們列出從起點出發,走次對角線,由左下到右上逐層拜訪的路徑。
題目會給我們一個routes 陣列,裡面都是分別代表每一條公車路線所對應的公車站編號。 題目要求我們計算出,從起點站source到終點站target的最精簡公車路線搭乘次數是幾次? 也就是說,就是在最少轉乘的前提下,旅途中需要搭乘幾條公車路線?
題目會給我們一個pair陣列,裡面都是原本陣列相鄰元素形成的pair,順序已經被打散。 要求我們從pair陣列重建出原本的陣列。 答案可能有不只一組,任選一組回傳即可。
題目會給定我們兩個點座標,分別是起點和終點。 另外,還有一個參數t,代表時間限制。 從起點出發之後,每一秒鐘,我們必須選擇一個N8 8連通的方向,往鄰居的格子點移動。(題目有特別強調,每一秒必須強制移動到下一個格子點,不能停留在原地) 請問我們能不能在時間限制內,從起點走到終點?
題目會給一顆二元樹,要求我們計算節點值 和 子樹平均值相等的node有幾個。
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
題目敘述 題目會給我們一個不規則排列的二維陣列,要求我們列出從起點出發,走次對角線,由左下到右上逐層拜訪的路徑。
題目會給我們一個routes 陣列,裡面都是分別代表每一條公車路線所對應的公車站編號。 題目要求我們計算出,從起點站source到終點站target的最精簡公車路線搭乘次數是幾次? 也就是說,就是在最少轉乘的前提下,旅途中需要搭乘幾條公車路線?
題目會給我們一個pair陣列,裡面都是原本陣列相鄰元素形成的pair,順序已經被打散。 要求我們從pair陣列重建出原本的陣列。 答案可能有不只一組,任選一組回傳即可。
題目會給定我們兩個點座標,分別是起點和終點。 另外,還有一個參數t,代表時間限制。 從起點出發之後,每一秒鐘,我們必須選擇一個N8 8連通的方向,往鄰居的格子點移動。(題目有特別強調,每一秒必須強制移動到下一個格子點,不能停留在原地) 請問我們能不能在時間限制內,從起點走到終點?
題目會給一顆二元樹,要求我們計算節點值 和 子樹平均值相等的node有幾個。
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
你可能也想看
Google News 追蹤
※ 查找 DOM 元素有兩種途徑: 直接選出一個節點 (select):要在樹狀結構裡查找資料,至少要先選出第一個元素。 從一個特定節點,查找到週邊的節點 :選出一個元素後,就可以順著結構找出父元素、子元素 、甚至同一層的兄弟元素,這種行為稱為「遍歷 (traverse)」。 ※ 選出特定 D
Thumbnail
Node 對我來說一直是很似懂非懂的概念,因為沒有實際可見的數字或字串實物可以觀察中間步驟,比起其他解題抽象許多。以下解題方法來自網友與 GPT 提供的答案,我想在本文中嘗試自己做視覺化圖解,說明 CodeWars - Can you get the loop ? 的解題思路。
Thumbnail
「A是B/B在A」主題為讓小朋友了解許多事情與物品像是一串一串的連結,讓孩子們能理解一樣物品背後會有很多連結。 認識柑橘類水果,哪個是柳丁?哪個是
Thumbnail
這裡是大直的好找豪宅區,因為這裡特別容易停車,所以很常來這裡散步。跟朋友邊走邊聊一些同學會的事情,還有當時小時候唸書的狀況。突然看到有幾個人在一個樹下不知道在講什麼東西。一看,朋友說:「你不知道嗎?那就是一個棗子樹。」 很多次走在這裡都沒有注意到它,只是沒想到現在結滿了。整顆樹都是棗子,也不知道是
大腦本身也符合第一性原理,其本質就在一切的結果裡。
Thumbnail
題目 : 28. Find the Index of the First Occurrence in a String
※ 查找 DOM 元素有兩種途徑: 直接選出一個節點 (select):要在樹狀結構裡查找資料,至少要先選出第一個元素。 從一個特定節點,查找到週邊的節點 :選出一個元素後,就可以順著結構找出父元素、子元素 、甚至同一層的兄弟元素,這種行為稱為「遍歷 (traverse)」。 ※ 選出特定 D
Thumbnail
Node 對我來說一直是很似懂非懂的概念,因為沒有實際可見的數字或字串實物可以觀察中間步驟,比起其他解題抽象許多。以下解題方法來自網友與 GPT 提供的答案,我想在本文中嘗試自己做視覺化圖解,說明 CodeWars - Can you get the loop ? 的解題思路。
Thumbnail
「A是B/B在A」主題為讓小朋友了解許多事情與物品像是一串一串的連結,讓孩子們能理解一樣物品背後會有很多連結。 認識柑橘類水果,哪個是柳丁?哪個是
Thumbnail
這裡是大直的好找豪宅區,因為這裡特別容易停車,所以很常來這裡散步。跟朋友邊走邊聊一些同學會的事情,還有當時小時候唸書的狀況。突然看到有幾個人在一個樹下不知道在講什麼東西。一看,朋友說:「你不知道嗎?那就是一個棗子樹。」 很多次走在這裡都沒有注意到它,只是沒想到現在結滿了。整顆樹都是棗子,也不知道是
大腦本身也符合第一性原理,其本質就在一切的結果裡。
Thumbnail
題目 : 28. Find the Index of the First Occurrence in a String