DFS應用題 計算與子樹平均值相等的節點數 Leetcode #2265

閱讀時間約 4 分鐘
raw-image

題目敘述

題目會給一顆二元樹,要求我們計算節點值 和 子樹平均值相等的node有幾個。

詳細的題目敘述在這裡:


測試範例

Example 1:

raw-image
Input: root = [4,8,5,0,1,null,6]
Output: 5
Explanation:
For the node with value 4: The average of its subtree is (4 + 8 + 5 + 0 + 1 + 6) / 6 = 24 / 6 = 4.
For the node with value 5: The average of its subtree is (5 + 6) / 2 = 11 / 2 = 5.
For the node with value 0: The average of its subtree is 0 / 1 = 0.
For the node with value 1: The average of its subtree is 1 / 1 = 1.
For the node with value 6: The average of its subtree is 6 / 1 = 6.

Example 2:

raw-image
Input: root = [1]
Output: 1
Explanation: For the node with value 1: The average of its subtree is 1 / 1 = 1.

約束條件

Constraints:

  • The number of nodes in the tree is in the range [1, 1000].
  • 0 <= Node.val <= 1000

演算法

抽象來想,對於當下節點來說,需要知道下列資訊來滿足題目要求的計算

  1. 子樹的結點值總和
  2. 子樹的valid count (就是子樹內部,節點值=子樹平均值的node count)
  3. 子樹的總結點數(因為平均 = 子樹結點值總和/子樹總結點數,我們會需要分子和分母的確切數值)


依循這個思路,設計DFS 遞迴function,以bottom-up 由下往上的方式,回傳 上述三個參數給parent node,逐層計算節點值 和 子樹平均值相等的node有幾個。


程式碼

class Solution:
 def averageOfSubtree(self, root: Optional[TreeNode]) -> int:
  
  def helper(root):

   if not root:
    # node value, valid count, total node count
    return 0, 0, 0
   
   l_sum, l_valid, l_nodes = helper(root.left)

   r_sum, r_valid, r_nodes = helper(root.right)

   # Average = (root + left subtree + right subtree) / subtree node count
   avg = (root.val + l_sum + r_sum) // (1 + l_nodes + r_nodes )

   if root.val == avg:
    return l_sum + r_sum + root.val, l_valid + r_valid + 1, l_nodes + r_nodes + 1
   
   else:
    return l_sum + r_sum + root.val, l_valid + r_valid, l_nodes + r_nodes + 1

  # ===========================
  # Our goal is valid count
  return helper(root)[1]

複雜度分析

時間複雜度:

O( n ) DFS 拜訪每個節點,每個節點拜訪一次。

空間複雜度:

O( n ) DFS 拜訪每個節點,最深深度為O(n),發生在整棵樹向左歪斜或向右歪斜時。


關鍵知識點

DFS function 傳統上都是回傳一個參數,或者直接return不帶回傳值。
這題的關鍵考點在於,我們需要的各種資訊都隱含在子樹裡,而且不只一個欄位。
接著想到,function其實可以return 多重欄位的回傳值,回傳給parent node 去計算題目所要求的目標值。


Reference:

[1] Python O(n) by DFS - Count Nodes Equal to Average of Subtree - LeetCode

avatar-img
90會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
題目會給我們節點總數目n、左子樹的關係陣列、右子樹的關係陣列,要求我們驗證在給定的條件下,能不能構成一顆合法的二元樹。
題目會給我們兩條已經從小到大排序好的串列,要求我們依照從小到大的順序,合併這兩條串列。
題目的輸入會給我們一個串列,要求我們從頭到尾反轉整個串列。 例子: 如果輸入是1 -> 2 -> 3,那麼輸出就是 3 -> 2 -> 1
題目會給定給我們一顆二元樹的根結點, 要求我們輸出上下顛倒的Level-order traversal的拜訪結果。
題目會給我們一顆二元樹的根節點, 要求我們對齊根節點正中央的虛擬分割線,反轉整顆二元樹。
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
題目會給我們節點總數目n、左子樹的關係陣列、右子樹的關係陣列,要求我們驗證在給定的條件下,能不能構成一顆合法的二元樹。
題目會給我們兩條已經從小到大排序好的串列,要求我們依照從小到大的順序,合併這兩條串列。
題目的輸入會給我們一個串列,要求我們從頭到尾反轉整個串列。 例子: 如果輸入是1 -> 2 -> 3,那麼輸出就是 3 -> 2 -> 1
題目會給定給我們一顆二元樹的根結點, 要求我們輸出上下顛倒的Level-order traversal的拜訪結果。
題目會給我們一顆二元樹的根節點, 要求我們對齊根節點正中央的虛擬分割線,反轉整顆二元樹。
你可能也想看
Google News 追蹤
Thumbnail
我們時常會發現有些問題不見得有標準答案,也會發現回答問題的人多半站在自己的立場思考,當我們聽到別人的答案時,是否會感到大吃一驚,原來從別人口中吐出的答案竟然是我們未曾想過的觀點! 《森林有多少樹?》這本書便是講述許多動物輪番表達自己對於森林應該有幾棵樹木的看法,每隻動物都基於自己的需求
Thumbnail
前言 如文章的封面圖片1/2~1/27總共有幾天呢? 如果你的答案是25天,那務必把這個日期的地雷搞懂 種樹問題計算 題目 一條路有50公尺,每10公尺種一棵樹,請問總共種了幾顆樹? 這時就會直覺,阿不就是50/10=5,總共種了5顆樹!! 但其實大錯特錯哦❌
Thumbnail
  在陽光灑落的後花園路上,有著新海城班因為課程討論而種植的綠豆, 這天~孩子們在帶著紙、筆紀錄的同時, 觀察到了走道上有著附近榕樹掉落的葉片...... 孩子:「老師,妳看~」 老師:「哇~好可愛耶!」 孩子:「對呀!我是撿地上的樹葉畫的。」   在孩子樂於分享、帶點被誇獎
Thumbnail
2024/03/30 斷頭樹沒有支點可以丟,而且長的一團亂非常茂密,非常難投擲豆袋,不小心豆袋就會卡在樹上。 這時候有兩個選擇,一個是繞住主幹的上方固定點,一個是投擲過最上方的基部固定點,但對於斷頭樹來說還是很難進行最上方徒長枝的修剪。 雖然我們知道斷頭修剪不好,但往往因為修剪預算不足
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
Node 對我來說一直是很似懂非懂的概念,因為沒有實際可見的數字或字串實物可以觀察中間步驟,比起其他解題抽象許多。以下解題方法來自網友與 GPT 提供的答案,我想在本文中嘗試自己做視覺化圖解,說明 CodeWars - Can you get the loop ? 的解題思路。
Thumbnail
這天,早會結束後,我們帶著孩子們到了後花園散步 ,孩子們發現有一棵樹上結滿了一顆一顆綠綠的果實... 幼兒:那是甚麼? 老師:哪個? 幼兒:綠綠的那個! 老師:我們也不知道耶,你們覺得呢? 幼兒:那個綠綠的!......是棗子! 老師:是嗎? 幼兒:對啦!是棗子!(此
Thumbnail
「A是B/B在A」主題為讓小朋友了解許多事情與物品像是一串一串的連結,讓孩子們能理解一樣物品背後會有很多連結。 認識柑橘類水果,哪個是柳丁?哪個是
Thumbnail
我們時常會發現有些問題不見得有標準答案,也會發現回答問題的人多半站在自己的立場思考,當我們聽到別人的答案時,是否會感到大吃一驚,原來從別人口中吐出的答案竟然是我們未曾想過的觀點! 《森林有多少樹?》這本書便是講述許多動物輪番表達自己對於森林應該有幾棵樹木的看法,每隻動物都基於自己的需求
Thumbnail
前言 如文章的封面圖片1/2~1/27總共有幾天呢? 如果你的答案是25天,那務必把這個日期的地雷搞懂 種樹問題計算 題目 一條路有50公尺,每10公尺種一棵樹,請問總共種了幾顆樹? 這時就會直覺,阿不就是50/10=5,總共種了5顆樹!! 但其實大錯特錯哦❌
Thumbnail
  在陽光灑落的後花園路上,有著新海城班因為課程討論而種植的綠豆, 這天~孩子們在帶著紙、筆紀錄的同時, 觀察到了走道上有著附近榕樹掉落的葉片...... 孩子:「老師,妳看~」 老師:「哇~好可愛耶!」 孩子:「對呀!我是撿地上的樹葉畫的。」   在孩子樂於分享、帶點被誇獎
Thumbnail
2024/03/30 斷頭樹沒有支點可以丟,而且長的一團亂非常茂密,非常難投擲豆袋,不小心豆袋就會卡在樹上。 這時候有兩個選擇,一個是繞住主幹的上方固定點,一個是投擲過最上方的基部固定點,但對於斷頭樹來說還是很難進行最上方徒長枝的修剪。 雖然我們知道斷頭修剪不好,但往往因為修剪預算不足
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
Node 對我來說一直是很似懂非懂的概念,因為沒有實際可見的數字或字串實物可以觀察中間步驟,比起其他解題抽象許多。以下解題方法來自網友與 GPT 提供的答案,我想在本文中嘗試自己做視覺化圖解,說明 CodeWars - Can you get the loop ? 的解題思路。
Thumbnail
這天,早會結束後,我們帶著孩子們到了後花園散步 ,孩子們發現有一棵樹上結滿了一顆一顆綠綠的果實... 幼兒:那是甚麼? 老師:哪個? 幼兒:綠綠的那個! 老師:我們也不知道耶,你們覺得呢? 幼兒:那個綠綠的!......是棗子! 老師:是嗎? 幼兒:對啦!是棗子!(此
Thumbnail
「A是B/B在A」主題為讓小朋友了解許多事情與物品像是一串一串的連結,讓孩子們能理解一樣物品背後會有很多連結。 認識柑橘類水果,哪個是柳丁?哪個是