題面
給定一個二叉樹,找到最長的路徑,這個路徑中的每個節點具有相同值。 這條路徑可以經過也可以不經過根節點。
兩個節點之間的路徑長度由它們之間的邊數表示,下面輸出 2
5
/ \
4 5
/ \ \
1 1 5
分析
- 將不同值樹拆解成多個同值子樹,求各子樹的最大路徑,取長
- 確定同值子樹的根節點,同值樹的參照值,如示例層序遍歷中選用第一個5為同值子樹根,而非下層5
- 遞迴求同值樹單邊最大路徑,遞迴體內比較取該同值樹最長路徑,對於同值樹而言最長路徑必經過根節點
拆解
不同值樹拆解為同值子樹過程
上述拆解,參考標準值依次為5,4,1,1
, 上層向下層帶值傳遞,父子不同拆分
同值子樹最大路徑,必經過根節點
每個同值連續節點最長路徑,即左路徑最長+右最長
程式碼
func longestUnivaluePath(root *TreeNode) int {
var rs int
var dfs func(*TreeNode,int) int
dfs = func(root *TreeNode, val int) int{
if root.Val != val { // 隱性表達該條件體外,當前節點值與參照標準值相等
dfs(root,root.Val) // 選定拆解為同值節點子樹根節點,及同值參照物
return -1 // 修正同值連續節點遞迴+1帶來的副作用
}
l,r:= 0,0
if root.Left != nil {
l = dfs(root.Left, val)+1 // 父子左連續,假定左值與參照值相同,計數加1
}
if root.Right != nil {
r= dfs(root.Right, val)+1 // 右連續計數
}
if cur := l+r; cur > rs { // 最大連續路徑數
rs = cur
}
if l > r { // 取單邊連續最大值
return l
}
return r
}
if root != nil {
dfs(root, root.Val)
}
return rs
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結