「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」
面试题 04.12. 求和路径
给定一棵二叉树,其中每个节点都含有一个整数数值(该值或正或负)。设计一个算法,打印节点数值总和等于某个给定值的所有路径的数量。注意,路径不一定非得从二叉树的根节点或叶节点开始或结束,但是其方向必须向下(只能从父节点指向子节点方向)。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
3
解释: 和为 22 的路径有:[5,4,11,2], [5,8,4,5], [4,11,7]
提示:
节点总数 <= 10000
暴力求解+递归
思路 根据题意可得我们需要求解数组中的所有从上到下节点的和等于sum的结果数
错误思路1:处理根节点,到达当前节点时,总数total的结果的所有情况,为了减少计算次数,我们会将上一次计算的结果直接传入,下一步只需要在pre的基础上继续向家,同时传入一个数组preArr,保留当前正在计算的节点的值
- total小于sum,这种情况我们只需要继续往下递归加上下一个节点的值即可
- total大于等于sum
- 等于sum的时候,res++
- 大于sum的时候,我想着减去前面的节点,就无需重新递归没一个节点从头计算了,所以从preArr中拿出最前面的节点,total = total - preArr[0], preArr = preArr.slice(1)
失败: 因为节点的值可能为负数,所以思路流产
暴力思路:
那当前是把每个节点都做首节点进行计算
- 声明res ,初始值为0
- 声明新的函数dealRoot用来递归处理每一个节点
- 声明computedTotal函数 计算从root到当前节点的值total
- 如果total等于sum那么res++
- 如果不等于则继续递归调用computedTotal,传入当前计算的total值方便计算 所有节点处理完毕后 ,返回res的值即可
var pathSum = function (root, sum) {
var res = 0
function dealRoot(root, sum) {
if (root === null) return 0
function computedTotal(root, sum, pre) {
if (root === null) return
var total = root.val + pre;
if (total === sum) {
res++
}
computedTotal(root.left, sum, total)
computedTotal(root.right, sum, total)
}
computedTotal(root, sum, 0)
dealRoot(root.left, sum, 0)
dealRoot(root.right, sum, 0)
}
dealRoot(root, sum)
return res
};