Path Sum问题


本文对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
}

参考资料

https://leetcode.com/problems/path-sum-iii/discuss/141424/Python-step-by-step-walk-through.-Easy-to-understand.-Two-solutions-comparison.-%3A-)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值