剑指Offer:二叉树中和为某一值的路径(一)

描述

给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n

例如:
给出如下的二叉树, sum=22
在这里插入图片描述

返回true,因为存在一条路径 5-> 4-> 11->→2的节点值之和为 22

我的思路

感觉很简单,就先乱写一下,应该会出错,出错了再改

int sum;
    public boolean hasPathSum (TreeNode root, int sum) {
        this.sum = sum;
        // write code here
        if (root == null || sum <= 0)
            return false;
        return travel(root,sum);
    }

    private boolean travel(TreeNode root, int path) {
        if (root == null || path <= 0){
            if (sum == 0)
                return true;
            else {
                path = sum;
                return false;
            }
        }
        travel(root.left,path - root.left.val);
        travel(root.right,path - root.right.val);
        return false;
    }

报错:
在这里插入图片描述
空指针异常了,我调试一下。是因为递归参数那里的问题,还是写少了。
这个代码跑通了我自己的测试,同时我发现我有个短板在于不知道该怎么写有返回值的递归,我每次都是用全局变量解决,但是这样我就对于递归过程非常不熟悉。还是得学习一下。

int sum,path;
    public boolean hasPathSum (TreeNode root, int sum) {
        this.sum = sum;
        // write code here
        if (root == null || sum <= 0)
            return false;
        travel(root,sum - root.val);//修改了这里
        if (path == 0)
            return true;
        else
            return false;
    }

    private void travel(TreeNode root, int path) {
        if (root == null || path <= 0){
            if (sum == 0)
                return;
            else {
                path = sum;
                return;
            }
        }
        travel(root.left,root.left != null ?path - root.left.val : 0);//是这边空指针异常
        travel(root.right,root.right != null ?path - root.right.val : 0);//加了个判断
    }

这个代码是测试用例没有跑通,就是只有两个节点的情况,根节点一个节点不算一条路径。
在这里插入图片描述
重新整理了思路又写了一个答案,结果还是有用例跑不通

int sum;
    public boolean hasPathSum (TreeNode root, int sum) {
        this.sum = sum;
        // write code here
        if (root == null || sum <= 0)
            return false;
        return travel(root,sum);
    }

    private boolean travel(TreeNode root, int path) {
        //重新整理思路,因为能力有限,上一个思路不知道该怎么判断叶子节点
        
        if (root == null)
            return false;

        path -= root.val;
        if (root.left == null && root.right == null && path == 0)//先判断返回true的逻辑吧
            return true;//其他情况就都返回false
        return travel(root.left,path) || travel(root.right,path);
    }

在这里插入图片描述
仔细一看属于我自己自作聪明,还对sum做了条件判断,典型没好好省题。

if (root == null || sum <= 0)
            return false;

放一下牛客跑通的代码

int sum;
    public boolean hasPathSum (TreeNode root, int sum) {
        this.sum = sum;
        // write code here
        if (root == null || sum <= 0)
            return false;
        return travel(root,sum);
    }

    private boolean travel(TreeNode root, int path) {
        //重新整理思路,因为能力有限,上一个思路不知道该怎么判断子节点
        //先判断返回true的逻辑吧
        if (root == null)
            return false;//不符合就回溯,我第一次写的代码还重新赋值。。有点傻

        path -= root.val;
        if (root.left == null && root.right == null && path == 0)
            return true;//其他情况就都返回false
        return travel(root.left,path) || travel(root.right,path);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值