本文对PathSum类的问题,进行一个总结
Path Sum
链接:https://leetcode.com/problems/path-sum/
这个直接看代码就好
func hasPathSum(root *TreeNode, targetSum int) bool {
if root == nil {
return false
}
if root.Left == nil && root.Right == nil {
if root.Val == targetSum {
return true
}
return false
}
if hasPathSum(root.Left, targetSum - root.Val) {
return true
}
if hasPathSum(root.Right, targetSum - root.Val) {
return true
}
return false
}
Path Sum II
链接:https://leetcode.com/problems/path-sum-ii/
基于Path Sum,我的解法如下:
func pathSum(root *TreeNode, targetSum int) [][]int {
if root == nil {
return nil
}
var res [][]int
if root.Left == nil && root.Right == nil {
if root.Val == targetSum {
res = append(res, []int{root.Val})
}
return res
}
left := pathSum(root.Left, targetSum - root.Val)
for _, v := range left {
tmp := []int{root.Val}
tmp = append(tmp, v...)
res = append(res, tmp)
}
right := pathSum(root.Right, targetSum - root.Val)
for _, v := range right {
tmp := []int{root.Val}
tmp = append(tmp, v...)
res = append(res, tmp)
}
return res
}
还有一种解法是backtracking,如下:
func pathSum(root *TreeNode, targetSum int) [][]int {
var res [][]int
var tmpList []int
res = backTracking(root, targetSum, res, tmpList)
return res
}
func backTracking(root *TreeNode, targetSum int, res [][]int, tmpList []int) [][]int {
if root == nil {
return res
}
tmpList = append(tmpList, root.Val)
if root.Left == nil && root.Right == nil && targetSum == root.Val {
res = append(res, construct(tmpList))
}
res = backTracking(root.Left, targetSum - root.Val, res, tmpList)
res = backTracking(root.Right, targetSum - root.Val, res, tmpList)
tmpList = tmpList[0:len(tmpList)-1]
return res
}
func construct(list []int) []int {
res := make([]int, len(list))
for i := 0; i < len(list); i++ {
res[i] = list[i]
}
return res
}
Path Sum III
链接:https://leetcode.com/problems/path-sum-iii/
这道题和上面2题又存在不一样了,我的解法比较粗暴
func pathSum(root *TreeNode, targetSum int) int {
if root == nil {
return 0
}
res := pathSum(root.Left, targetSum)
res += pathSum(root.Right, targetSum)
// 找包含root的结点
res += helper(root, targetSum)
return res
}
// 找从根节点开始的等于val的path总数
func helper(root *TreeNode, val int) int {
if root == nil {
return 0
}
var res int
if root.Val == val {
res++
}
res += helper(root.Left, val - root.Val)
res += helper(root.Right, val - root.Val)
return res
}
优化解法类似于two-sum,
func pathSum(root *TreeNode, targetSum int) int {
// key: prefixSum, val: freq
mp := make(map[int]int)
mp[0] = 1
var cnt int
cnt = dfs(root, 0, targetSum, mp, 0)
return cnt
}
func dfs(root *TreeNode, curSum int, targetSum int, mp map[int]int, cnt int) int {
if root == nil {
return cnt
}
curSum += root.Val
v := mp[curSum - targetSum]
cnt += v
mp[curSum] += 1
cnt = dfs(root.Left, curSum, targetSum, mp, cnt)
cnt = dfs(root.Right, curSum, targetSum, mp, cnt)
mp[curSum] -= 1
return cnt
}