每日一题 -- 树
二叉树的坡度
反思
- 这道题因为在双递归的章节中出现,所以一开始就想用双递归的形式去做,其实思路应该是没问题的,先进行一次递归更新所有节点的值为当前子树的和,然后第二次递归直接求和
- 但是不晓得怎么写着写着就偏到内外递归,导致乱七八糟,最终实现的是以一个单递归
// https://leetcode-cn.com/problems/binary-tree-tilt/description/
/**
* 双递归
* @分析 (错误)
* 1. 内递归求每个节点左右树对应的总值,为坡度求值做准备,这个要用自底向上的方式求出
* 2. 外递归的时候,只需要用左右节点的总和即可求出对应的坡度
*
* @踩过的坑
* 1. 本来只需要两次递归,第一次只要走一遍就结束递归,得到新树就可以了,第二次就根据新树求总和
* 2. 彻底拉胯。一道简单题搞了80min,上述分析是一开始的分析,彻底错误,下面是后面做出来之后的分析
*
*/
// var findTilt = function(root) {
// // 自底向上更新当前的节点值,并返回当前节点的坡度
// const innerDfs = (root) =>{
// if(!root) return 0
// const left = root.left?root.left.val : 0
// const right = root.right? root.right.val : 0
// const total = root.val + left + right
// root.val = total
// return Math.abs(left-right)
// }
// // 自顶向下求出每个节点的坡度
// const wrapperDfs = root => {
// if(!root) return 0
// const left = wrapperDfs(root.left)
// const right = wrapperDfs(root.right)
// const cur = innerDfs(root)
// return cur+left+right
// }
// return wrapperDfs(root)
// };
/**
* @分析 实际是单递归
* 1. 自底向上更新当前的节点值,并返回当前节点的坡度
*/
var findTilt = function (root) {
let res = 0
// 自顶向下求出每个节点的坡度
const wrapperDfs = root => {
if (!root) return
wrapperDfs(root.left)
wrapperDfs(root.right)
const curLeft = root.left ? root.left.val : 0
const curRight = root.right ? root.right.val : 0
const total = root.val + curLeft + curRight
// 更新当前节点的值
root.val = total
// 求出当前节点的坡度
res += Math.abs(curLeft - curRight)
}
wrapperDfs(root)
return res
};
大力出奇迹
- 可能是因为早期没睡醒,所以一直没弄好的双递归,在我决定就但递归结束这道题,写写感想的时候,就捋清了
- 所以还是大力出奇迹,多写写感想,多做题,或许灵感就出来了,欧力给
/**
* 然后再分析过程中,终于知道双递归是咋回事了
*/
var findTilt = function (root) {
let res = 0
const dfs1 = root => {
if(!root) return 0
const left = dfs1(root.left)
const right = dfs1(root.right)
const total = root.val + left+right
root.val = total
return total
}
dfs1(root)
const dfs2 = root => {
if(!root) return
const left = root.left?root.left.val:0
const right = root.right?root.right.val:0
res+= Math.abs(left-right)
dfs2(root.left)
dfs2(root.right)
}
dfs2(root)
return res
}