javascript中二叉树的回溯与双指针

如果说二叉树的遍历属于基础部分,那二叉树中的回溯与双指针就属于进阶内容了,但不不用担心这两个技巧并不难。
接下来我们来看一道经典的力扣题:
112.路径总和(经典回溯)
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

本题我们需要找一条符合条件的路径,而这个二叉树并不是搜索二叉树,只能采用穷举的方法,而穷举也是有技巧的,并不是一次一次从跟节点穷举,而是通过子节点返回的值判断穷举是否成功,否则就回溯。回溯虽然挺起来挺高大上的,其实在二叉树中大部分都是通过递归解决问题,而如果递归函数中有意义明确的返回值,基本上就会有回溯的过程,所以回溯的关键即就在于返回值的确定以及对返回值的处理

那么接下来就简单了许多,只需要按照递归三件套进行即可。

  1. 确定递归函数的参数与返回类型
    参数:需要二叉树的根节点,还需要一个计数器,这个计数器用来计算二叉树的一条边之和是否正好是目标和。
    返回值:如果计数器归0说明穷举成功返回true,而既然子节点若返回true,那么父节点也即返回ture返回到顶层即可,若为false则返回false。

  2. 确定终止条件
    不要去累加然后判断是否等于目标和,那么代码比较麻烦,可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。

    如果最后count == 0,同时到了叶子节点的话,说明找到了目标和返回true。

    如果遍历到了叶子节点,count不为0,就是没找到返回false。

  3. 确定单层逻辑
    因为终止条件是判断叶子节点,所以递归的过程中就不要让空节点进入递归了。

    递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。

完整代码:

/**
 * 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} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
    function dfs(node,count){
        if(count===0&&!node.left&&!node.right) return true//找到了节点
        if(!node.left&&!node.right) return false //未找到节点
        if(node.left){
            count-=node.left.val
            if(dfs(node.left,count)) return true
            count+=node.left.val//未命中,则回溯
        }
        if(node.right){
            count-=node.right.val
            if(dfs(node.right,count)) return true
            count+=node.right.val//未命中,则回溯
        }
        return false
    }
    if(!root) return false
    return dfs(root,targetSum-root.val)
 }

501.二叉树中的众数(双指针)
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

  1. 给定一个pre初始值为root,在放入root.left后pre更新为root.left
  2. 没次递归拿pre与cur进行比较即可

完整代码:

var findMode = function(root) {
    // 不使用额外空间,使用中序遍历,设置出现最大次数初始值为1
    let count = 0,maxCount = 1;
    let pre = root,res = [];
    // 1.确定递归函数及函数参数
    const travelTree = function(cur) {
        // 2. 确定递归终止条件
        if(cur === null) {
            return ;
        }
        travelTree(cur.left);
        // 3. 单层递归逻辑
        if(pre.val === cur.val) {
            count++;
        }else {
            count = 1;
        }
        pre = cur;
        if(count === maxCount) {
            res.push(cur.val);
        }
        if(count > maxCount) {
            res = [];
            maxCount = count;
            res.push(cur.val);
        }
        travelTree(cur.right);
    }
    travelTree(root);
    return res;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值