You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf
, but it must go downwards (traveling only from parent nodes to child nodes).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
Example
:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 810/ \5 -3/ \ \3 2 11/ \ \3 -2 1Return 3. The paths that sum to 8 are:1. 5 -> 32. 5 -> 2 -> 13. -3 -> 11
此题的难点需想清每个节点都要当作根节点
来对待, 因此题解为如下三部分之和:
当前节点作为根节点
时相加为 sum 的路径之和。当前节点左子树作为根节点
时相加为 sum 的路径之和。当前节点右子树作为根节点
时相加为 sum 的路径之和。同时递归可以分为两个部分: 根节点的递归
与 分析总和的递归
。
/*** Definition for a binary tree node.* function TreeNode(val, left, right) {* this.val = (val===undefined ? 0 : val)* this.left = (left===undefined ? null : left)* this.right = (right===undefined ? null : right)* }*//*** @param {TreeNode} root* @param {number} sum* @return {number}*/var pathSum = function(root, sum) {if (!root) return 0// total means result value// initialSum means init sum valuelet result = { total: 0, initialSum: sum }analyzeSum(root, result, sum)return result.total};var analyzeSum = function(node, result, sum) {if (!node) returnconst extraSum = sum - node.valif (extraSum === 0) {result.total = result.total + 1}analyzeSum(node.left, result, extraSum)analyzeSum(node.right, result, extraSum)// handle it as root node.analyzeSum(node.left, result, result.initialSum)analyzeSum(node.right, result, result.initialSum)}
submit 后, 卡在了如下测试用例中:
输入:[1,null,2,null,3] // 该测试用例有点怪, 应该为 [1, null, 2, null, null, null, 3]31/ \null 2/ \null 3输出:3预期:2
经过排查, analyzeSum
函数存在冗余的调用, 并未将根节点的递归
与分析总和的递归
给解耦。调整如下:
/*** Definition for a binary tree node.* function TreeNode(val, left, right) {* this.val = (val===undefined ? 0 : val)* this.left = (left===undefined ? null : left)* this.right = (right===undefined ? null : right)* }*//*** @param {TreeNode} root* @param {number} sum* @return {number}*/// recursive root nodevar pathSum = function(root, sum) {if (!root) return 0const curTotal = analyzeSum(root, sum)const leftChildTotal = pathSum(root.left, sum)const rightChildTotal = pathSum(root.right, sum)return curTotal + leftChildTotal + rightChildTotal};// recursive anlyze total valuevar analyzeSum = function(node, expectSum) {if (!node) return 0const extraSum = expectSum - node.valif (extraSum === 0) {return 1 + analyzeSum(node.left, extraSum) + analyzeSum(node.right, extraSum)} else {return analyzeSum(node.left, extraSum) + analyzeSum(node.right, extraSum)}}