專題講解 樹專題 遞迴思路處理樹

2021-10-05 00:17:03 字數 4456 閱讀 4308

我們都以二叉樹作為乙個標準的例子分析樹的問題常用的方法。

首先我們先來分析遞迴的方法。有乙個很好的二叉樹的三步走戰略,我覺著很值得學習。

「三步走」方法的三步分別為:

可以看出,核心有兩個,乙個是拆解子問題,乙個是是否使用全域性變數。

全域性變數的使用很靈活的,因為python是可以返回多個變數,因此只是乙個可選項。

接下來已一些例子分析如何拆解子問題和如何抉擇全域性變數。

一般情況下二叉樹的問題都是可以分為左右子樹的問題和考慮根節點參與的問題。

使用全域性變數時候,只需要分析什麼時候可能產生新的最大值。也就是當前根節點參與進去的情況。

不使用全域性變數,就要分析左右子樹的情況

# 採用全域性變數

class

solution

(object):

def__init__

(self)

: self.ans =

0def

longestunivaluepath

(self, root)

:"""

:type root: treenode

:rtype: int

"""ifnot root:

return

0 self.helper(root)

return self.ans

defhelper

(self, root):if

not root:

return self.ans

left = self.helper(root.left)

right = self.helper(root.right)

if root.left and root.left.val == root.val:

left +=

1else

: left =

0if root.right and root.right.val == root.val:

right +=

1else

: right =

0 self.ans =

max(self.ans, right+left)

return

max(right, left)

# 不採用全域性變數

主問題:多少個符合的路徑

不採用全域性變數:

核心思想,單獨分析根節點參與的情況

因此需要寫為兩個函式

採用全域性變數:

# 不採用全域性變數

class

solution

:def

pathsum

(self, root: treenode,

sum:

int)

->

int:

ifnot root:

return

0return self.pathsum(root.left,

sum)

+self.pathsum(root.right,

sum)

+self.pathstarsum(root,

sum)

defpathstarsum

(self, root,

sum):if

not root:

return

0 res =

0if root.val ==

sum:

res +=

1

res += self.pathstarsum(root.left,

sum-root.val)

+self.pathstarsum(root.right,

sum-root.val)

return res

# 採用全域性變數

class

solution

(object):

def__init__

(self)

: self.res =

0def

pathsum

(self, root,

sum)

:"""

:type root: treenode

:type sum: int

:rtype: int

"""dic =

self.helper(root,

sum,

0,dic)

return self.res

defhelper

(self,root,

sum,cur,dic):if

not root:

return

cur += root.val

self.res += dic.get(cur-

sum,0)

# 回溯

dic[cur]

= dic.get(cur,0)

+1self.helper(root.left,

sum,cur,dic)

self.helper(root.right,

sum,cur,dic)

## 為了轉向二叉樹的另外一側,需要刪除包含當前節點的,理解:從root.left到 root.right

dic[cur]

-=1

再補充一道如何單獨分析根節點的。這個方法在題目問題含有起始點等設定時有效。

明顯這個子樹是需要有乙個起始點的,因此我們主問題變成:左側含有子樹+右側含有子樹+當前點展開子樹。

class

solution

:def

issubtree

(self, s: treenode, t: treenode)

->

bool:if

not s:

return

false

return self.issubtree(s.right, t)

or self.issubtree(s.left, t)

or self.rootissubtree(s, t)

# 單獨考慮了根節點作為起點的情況

defrootissubtree

(self, s, t):if

not s and

not t:

return

true

ifnot s or

not t:

return

false

if s.val == t.val:

return self.rootissubtree(s.right, t.right)

and self.rootissubtree(s.left, t.left)

樹的遞迴專題

leetcode 543.二叉樹的直徑 給定一棵二叉樹,你需要計算它的直徑長度。一棵二叉樹的直徑長度是任意兩個結點路徑長度中的最大值。這條路徑可能穿過根結點。示例 給定二叉樹 1 2 3 4 5 返回 3,它的長度是路徑 4,2,1,3 或者 5,2,1,3 注意 兩結點之間的路徑長度是以它們之間邊...

樹套樹專題

對資料結構的不熟練 題目鏈結 嘗試一下樹狀陣列套主席樹的寫法。小細節沒有重視 為了方便起見,一般我們寫getrank x 求的都是 1 include2 const int maxn 50035 3 const int maxnode 5000035 4 const int inf 21474836...

線段樹專題

最最基礎的線段樹,只更新葉子節點,然後把資訊用pushup int r 這個函式更新上來。hdu1166 敵兵布陣 線段樹 hdu 1166 敵兵布陣 單點更新區間求和 hdu1754 i hate it 線段樹 hdu 1754 i hate it 單點更新 區間求最值 hdu1394 minim...