437.路径总和 III

58 阅读1分钟

题目:
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
算法: 方法一: 暴力+DFS 主要要划分好条件和子函数。 搜索的路径包括root节点:rootSum(root) 搜搜的路径不包括root节点:pathSum(root.Left)+pathSum(root.Right)

 func pathSum(root *TreeNode, targetSum int) int {
    if root == nil {
        return 0
    }
	return rootSum(root, targetSum) + pathSum(root.Left, targetSum) + pathSum(root.Right, targetSum)
}

func rootSum(root *TreeNode, targetSum int) int {
	if root == nil {
		return 0
	}

	sum := 0
	if root.Val == targetSum {
		sum ++
	}
	sum = sum + rootSum(root.Left, targetSum - root.Val) + rootSum(root.Right, targetSum - root.Val)
	
	return sum 
}

方法二
回溯+前缀和 数和数组的路径和都可以转换为前缀和

func pathSum(root *TreeNode, targetSum int) int {
    prefixSumMap := make(map[int]int)
	// 【 不需要从根节点开始,也不需要在叶子节点结束】 一个节点都不选的选择有一个
	prefixSumMap[0] = 1
	return doPathSum(root, prefixSumMap, 0, targetSum)
}

func doPathSum(root *TreeNode, prefixSumMap map[int]int, curPrefixSum, targetSum int) int {
	if root == nil {
		return 0
	}
	curPrefixSum = curPrefixSum + root.Val
	sum :=  prefixSumMap[curPrefixSum - targetSum]
	prefixSumMap[curPrefixSum] ++
	left := doPathSum(root.Left, prefixSumMap, curPrefixSum, targetSum)
	right := doPathSum(root.Right, prefixSumMap, curPrefixSum, targetSum)
	prefixSumMap[curPrefixSum] --
	return sum + left + right
}