圖論應用題: 樹的路徑總和 Path Sum_Leetcode #112

更新於 發佈於 閱讀時間約 7 分鐘


題目敘述

題目會給定一顆二元樹的根結點Root node,和指定的目標值targetSum。

問我們能不能從二元樹裡面找到一條從根結點到葉子結點的路徑,其路徑上的節點值總和恰好為targetSum?

可以的話,返回True。

無解的話,返回False。


題目的原文敘述


測試範例

Example 1:

raw-image
Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
Output: true
Explanation: The root-to-leaf path with the target sum is shown.

Example 2:

raw-image
Input: root = [1,2,3], targetSum = 5
Output: false
Explanation: There two root-to-leaf paths in the tree:
(1 --> 2): The sum is 3.
(1 --> 3): The sum is 4.
There is no root-to-leaf path with sum = 5.

Example 3:

Input: root = [], targetSum = 0
Output: false
Explanation: Since the tree is empty, there are no root-to-leaf paths.

請注意,空樹對應到的是無解喔,要返回False

約束條件

Constraints:

  • The number of nodes in the tree is in the range [0, 5000].

結點總數目介於0~5000之間。

請留意邊界條件的處理,題目有可能給我們一顆空樹

  • -1000 <= Node.val <= 1000

節點值都介於 負一千 ~ 正一千之間。

  • -1000 <= targetSum <= 1000

目標值targetSum 一定介於 負一千 ~ 正一千 之間。


演算法

題目已經說從二元樹裡面,看看能不能找到一條從根結點到葉子結點的路徑,其路徑上的節點值總和恰好為targetSum?

那就順著題意走從Root node根結點出發,從上往下走,每經過一個節點,就把targetSum減去對應的結點值node.val,假如到葉子結點的時候,targetSum剛好扣完,那就表示有解,返回True

否則,假如都找不到,代表無解,返回False。


程式碼 DFS從上到下深度優先搜索每個結點

class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:

## Base case: Empty tree or empty node
if not root:
return False

## Base case
if not root.left and not root.right:

# we have the path with targetSum
return targetSum == root.val

## General case:
return self.hasPathSum(root.left, targetSum - root.val) or \
self.hasPathSum(root.right, targetSum - root.val)

複雜度分析 DFS從上到下深度優先搜索每個結點

時間複雜度:

從根結點開始,探索整顆樹,每個結點最多拜訪一次,所需時間為O(n)。

空間複雜度:

從根結點開始,探索整顆樹,遞迴深度最深為n,發生在整顆樹向左歪斜或向右歪斜的時候,所需recursion call stack最深為O(n)。


程式碼 BFS從上到下 廣度優先,逐層往下探索每個結點

class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:

# Base case: empty tree
if not root:
return False

# BFS Queue, starting from root node with given targetSum
bfs_q = deque([ (root, targetSum)])

# Launch BFS aka level-order traversal from root node
while bfs_q:

cur, target = bfs_q.popleft()

# We've reached leaf node, and my value equals to target value
if not cur.left and not cur.right and target == cur.val:
return True

# Update target value for next level
target -= cur.val

# Push children into BFS queue
cur.left and bfs_q.append( (cur.left, target) )
cur.right and bfs_q.append( (cur.right, target) )

return False

複雜度分析 BFS從上到下 廣度優先,逐層往下探索每個結點

時間複雜度:

從根結點開始,探索整顆樹,每個結點最多拜訪一次,所需時間為O(n)。

空間複雜度:

從根結點開始,探索整顆樹,BFS Queue長度最長為O(n/2),發生最後一層而且樹全滿的時候,所需空間最大為O(n/2) = O(n) 係數可省略。


關鍵知識點

順著題意走從Root node根結點出發,從上往下走,每經過一個節點,就把targetSum減去對應的結點值node.val,假如到葉子結點的時候,targetSum剛好扣完,那就表示有解,返回True

否則,代表無解,返回False。


Reference:

[1] Path Sum_Python O(n) DFS solution

[2] Path Sum_Python O(n) BFS solution

avatar-img
91會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
題目敘述 題目會給定兩顆二元樹的根結點,要求我們判斷這兩顆二元樹是否為 葉子相似樹? 葉子相似樹的定義 兩顆二元樹,從左到右看的葉子結點的序列完全相同。 例如下圖中的這兩顆二元樹,從左到右看的葉子結點的序列 = [6, 7, 4, 9, 8] 完全相同。 題目的原文敘述 測試範例
題目敘述 題目會給定一個二元樹的樹根結點Root node,要求我們計算這顆二元樹的最大深度是多少? 二元樹的深度的定義: 從根結點到葉子結點的最大路徑長度。 題目的原文敘述 約束條件 Constraints: The number of nodes in the tree is
題目敘述 題目會給我們一個輸入陣列arr,起始點固定在索引為0的位置, 終點固定在索引為n-1的位置。 假設當下所在的索引位置為i,那麼每次移動的時候,可以跳到i-1,i+1,或者其他和我有相同元素值的位置arr[j], where arr[j] = arr[i]。 例如: 假設當下在i=3
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以左右位移的固定長度。 例如,假設 nums[i] = 3,那麼下一步可以移動到nums[i-3] 或 nums[i+3]這兩個格子點。 題目​會給定一個起始點start索引位置,請問我們能不能走到內部數值為0的格子點?
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以跳躍的最大長度。 題目保證始從最左邊的格子點出發開始跳,一定可以成功抵達終點,請問最少跳躍次數是說少? 題目的原文敘述 測試範例 Example 1: Input: nums = [2,3,1,1,4] Outp
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以跳躍的最大長度。 一開始從最左邊的格子點出發開始跳,請問可以成功抵達終點,也就是最右邊的格子點嗎? 如果可以,返回 True。 如果不行,返回False。 題目的原文敘述 測試範例 Example 1: In
題目敘述 題目會給定兩顆二元樹的根結點,要求我們判斷這兩顆二元樹是否為 葉子相似樹? 葉子相似樹的定義 兩顆二元樹,從左到右看的葉子結點的序列完全相同。 例如下圖中的這兩顆二元樹,從左到右看的葉子結點的序列 = [6, 7, 4, 9, 8] 完全相同。 題目的原文敘述 測試範例
題目敘述 題目會給定一個二元樹的樹根結點Root node,要求我們計算這顆二元樹的最大深度是多少? 二元樹的深度的定義: 從根結點到葉子結點的最大路徑長度。 題目的原文敘述 約束條件 Constraints: The number of nodes in the tree is
題目敘述 題目會給我們一個輸入陣列arr,起始點固定在索引為0的位置, 終點固定在索引為n-1的位置。 假設當下所在的索引位置為i,那麼每次移動的時候,可以跳到i-1,i+1,或者其他和我有相同元素值的位置arr[j], where arr[j] = arr[i]。 例如: 假設當下在i=3
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以左右位移的固定長度。 例如,假設 nums[i] = 3,那麼下一步可以移動到nums[i-3] 或 nums[i+3]這兩個格子點。 題目​會給定一個起始點start索引位置,請問我們能不能走到內部數值為0的格子點?
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以跳躍的最大長度。 題目保證始從最左邊的格子點出發開始跳,一定可以成功抵達終點,請問最少跳躍次數是說少? 題目的原文敘述 測試範例 Example 1: Input: nums = [2,3,1,1,4] Outp
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以跳躍的最大長度。 一開始從最左邊的格子點出發開始跳,請問可以成功抵達終點,也就是最右邊的格子點嗎? 如果可以,返回 True。 如果不行,返回False。 題目的原文敘述 測試範例 Example 1: In
你可能也想看
Google News 追蹤
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
前言 如文章的封面圖片1/2~1/27總共有幾天呢? 如果你的答案是25天,那務必把這個日期的地雷搞懂 種樹問題計算 題目 一條路有50公尺,每10公尺種一棵樹,請問總共種了幾顆樹? 這時就會直覺,阿不就是50/10=5,總共種了5顆樹!! 但其實大錯特錯哦❌
Thumbnail
這篇文章,會帶著大家複習以前學過的BFS框架, 並且以圖論的應用題與概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 BFS 框架 + 演算法 虛擬碼 # Queue 通常初始化成根結點,作為起點 BFS_queue = deque([root])​ # 先
Thumbnail
題目敘述 題目會給定一棵二元樹的根結點, 要求我們計算滿足局部路徑節點和=targetSum的數目有多少? 註: 局部路徑節點和 =由節點a往下走到某個節點b,這個區間內的節點值總和 題目的原文敘述 測試範例 Example 1: Input: root = [10,5,-3,3
Thumbnail
題目敘述 題目會給我們一串相鄰矩陣isConnected,相鄰矩陣的元素值isConnected[i][j] 代表第i座城市和第j座城市是否有連通。 如果彼此有連通,則isConnected[i][j]=1。 如果彼此沒有連通,則isConnected[i][j]=0。 彼此互相有路徑可以
Thumbnail
題目敘述 題目會給定一顆二元樹的根結點Root node,和指定的目標值targetSum。 問我們能不能從二元樹裡面找到一條從根結點到葉子結點的路徑,其路徑上的節點值總和恰好為targetSum? 可以的話,返回True。 無解的話,返回False。 題目的原文敘述 測試範例 E
Thumbnail
題目敘述 題目會給定兩顆二元樹的根結點,要求我們判斷這兩顆二元樹是否為 葉子相似樹? 葉子相似樹的定義 兩顆二元樹,從左到右看的葉子結點的序列完全相同。 例如下圖中的這兩顆二元樹,從左到右看的葉子結點的序列 = [6, 7, 4, 9, 8] 完全相同。 題目的原文敘述 測試範例
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
前言 如文章的封面圖片1/2~1/27總共有幾天呢? 如果你的答案是25天,那務必把這個日期的地雷搞懂 種樹問題計算 題目 一條路有50公尺,每10公尺種一棵樹,請問總共種了幾顆樹? 這時就會直覺,阿不就是50/10=5,總共種了5顆樹!! 但其實大錯特錯哦❌
Thumbnail
這篇文章,會帶著大家複習以前學過的BFS框架, 並且以圖論的應用題與概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 BFS 框架 + 演算法 虛擬碼 # Queue 通常初始化成根結點,作為起點 BFS_queue = deque([root])​ # 先
Thumbnail
題目敘述 題目會給定一棵二元樹的根結點, 要求我們計算滿足局部路徑節點和=targetSum的數目有多少? 註: 局部路徑節點和 =由節點a往下走到某個節點b,這個區間內的節點值總和 題目的原文敘述 測試範例 Example 1: Input: root = [10,5,-3,3
Thumbnail
題目敘述 題目會給我們一串相鄰矩陣isConnected,相鄰矩陣的元素值isConnected[i][j] 代表第i座城市和第j座城市是否有連通。 如果彼此有連通,則isConnected[i][j]=1。 如果彼此沒有連通,則isConnected[i][j]=0。 彼此互相有路徑可以
Thumbnail
題目敘述 題目會給定一顆二元樹的根結點Root node,和指定的目標值targetSum。 問我們能不能從二元樹裡面找到一條從根結點到葉子結點的路徑,其路徑上的節點值總和恰好為targetSum? 可以的話,返回True。 無解的話,返回False。 題目的原文敘述 測試範例 E
Thumbnail
題目敘述 題目會給定兩顆二元樹的根結點,要求我們判斷這兩顆二元樹是否為 葉子相似樹? 葉子相似樹的定義 兩顆二元樹,從左到右看的葉子結點的序列完全相同。 例如下圖中的這兩顆二元樹,從左到右看的葉子結點的序列 = [6, 7, 4, 9, 8] 完全相同。 題目的原文敘述 測試範例