【牛客 - 剑指offer】JZ34 二叉树中和为某一值的路径(二) Java实现 两种方案


剑指offer题解汇总 Java实现

https://blog.csdn.net/guliguliguliguli/article/details/126089434

本题链接

知识分类篇 - 树 - JZ34 二叉树中和为某一值的路径(二)

题目

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

思路 & 代码

题目主要信息

  • 给出一棵树的根节点指针,和一个期待值

  • 要在这棵树中找出从根节点到叶子节点的路径上的节点值之和等于该期待值的路径,找出所有这样的路径并返回

方案一 深度优先搜索dfs

深度优先搜索一般用于树或者图的遍历,其他有分支的(如二维矩阵)也适用。它的原理是从初始化点开始,一直沿着同一个分支遍历,直到该分支结束,然后回溯到上一级继续沿着一个分支走到底,如此往复,直到所有的节点都有被访问到。

思路

从根节点开始向左右子树进行递归,递归函数中需要处理的是:

  1. 当前路径path要更新

  2. 当前的目标值expectNumber要迭代,减去当前节点的值

  3. 若当前节点是叶子节点,考虑是否满足路径的期待值,并考虑是否将路径添加到返回列表中

注意

  • 在提交的时候需要删掉@Test标识的方法,删除import org.junit.Test;这一行导包

  • 擅用Debug功能

  • 我认为需要注意的是ret.add(new ArrayList<>(path));必须创建一个新的arrayList来存放path,如果只是把path添加到ret中,在对path进行修改时,ret中存储的path也会相应更改,产生错误

import org.junit.Test;

import java.util.*;
import java.util.ArrayList;

/**
 * public class TreeNode {
 * int val = 0;
 * TreeNode left = null;
 * TreeNode right = null;
 * <p>
 * public TreeNode(int val) {
 * this.val = val;
 * <p>
 * }
 * <p>
 * }
 */
public class Solution {

    private ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
    private ArrayList<Integer> path = new ArrayList<>();

    void dfs(TreeNode node, int number) {
        if (node == null) {
            return;
        }
        //路径更新
        path.add(node.val);
        //number更新
        number -= node.val;
        //如果当前是叶子节点,且该条路的值达到了expectNumber
        if (node.right == null && node.left == null && number == 0) {
            ret.add(new ArrayList<>(path));
        }

        //遍历左子树
        dfs(node.left, number);
        //遍历右子树
        dfs(node.right, number);
        path.remove(path.size() - 1);

    }

    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int expectNumber) {
        dfs(root, expectNumber);
        return ret;
    }

    @Test
    public void test() {
        TreeNode n1 = new TreeNode(10);
        TreeNode n2 = new TreeNode(5);
        TreeNode n3 = new TreeNode(12);
        TreeNode n4 = new TreeNode(4);
        TreeNode n5 = new TreeNode(7);

        n1.left = n2;
        n1.right = n3;

        n2.left = n4;
        n2.right=n5;

        ArrayList<ArrayList<Integer>> arrayLists = FindPath(n1, 22);
        System.out.println(arrayLists);
    }
}

方案二 广度优先搜索bfd

队列是一种仅支持在表尾进行插入操作、在表头进行删除操作的线性表,插入端称为队尾,删除端称为队首,因整体类似排队的队伍而得名

  • 元素入队,将新元素加在队列的队尾

  • 元素出队,将队首元素取出,它的后一个为新的队首

思路

深度优先搜索是优先一条路走到底,而广度优先搜索是按照二叉树的层进行搜索,因此路径需要逐层进行记录,我们引入队列来维护这个逐层路径的信息

  • pathQ存储了所有的路径

  • 当遍历到叶子结点的时候,把当前的路径拿出来,检查所有节点的加和是不是和形参expectNumber

    • 满足条件的话,则把这个队列,加入ret
import org.junit.Test;

import java.util.*;
import java.util.ArrayList;

public class Solution {
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int expectNumber) {

        ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
        if (root == null) {
            return ret;
        }
        //存储路径和存储节点的是对应的
        //存储路径,所有情况的列表总和
        LinkedList<ArrayList<Integer>> pathQ = new LinkedList<>();
        //存储节点
        LinkedList<TreeNode> nodeQ = new LinkedList<>();

        pathQ.add(new ArrayList<Integer>(Arrays.asList(root.val)));
        nodeQ.add(root);

        while (!nodeQ.isEmpty()) {
            //poll 查询并移除第一个元素
            ArrayList<Integer> curPath = pathQ.poll();
            TreeNode curNode = nodeQ.poll();
            if (curNode.left == null && curNode.right == null) {
                ArrayList<Integer> l = curPath;
                int sum = 0;
                for (Integer integer : l) {
                    sum += integer;
                }
                if (sum == expectNumber) {
                    ret.add(l);
                }
            }
            if (curNode.left != null) {
                //创建一个arrayList
                ArrayList<Integer> left = new ArrayList<>(curPath);

                //向left中添加当前节点的值
                left.add(curNode.left.val);

                pathQ.add(left);

                //节点路径添加left节点
                nodeQ.add(curNode.left);
            }
            if (curNode.right != null) {
                ArrayList<Integer> right = new ArrayList<>(curPath);

                right.add(curNode.right.val);

                pathQ.add(right);

                nodeQ.add(curNode.right);
            }

        }
        return ret;
    }

    @Test
    public void test() {
        TreeNode n1 = new TreeNode(10);
        TreeNode n2 = new TreeNode(5);
        TreeNode n3 = new TreeNode(12);
        TreeNode n4 = new TreeNode(4);
        TreeNode n5 = new TreeNode(7);

        n1.left = n2;
        n1.right = n3;

        n2.left = n4;
        n2.right=n5;

        ArrayList<ArrayList<Integer>> arrayLists = FindPath(n1, 22);
        System.out.println(arrayLists);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目要求:给定一个二叉树和一个整数target,找出所有从根节点到叶子节点路径之和等于target的路径。 解题思路:可以使用深度优先搜索(DFS)的方法来解决该问题。首先定义一个辅助函数来进行递归搜索,该辅助函数的参数包括当前节点、当前路径、当前路径的和以及目标和。在搜索过程,需要维护一个数组来保存当前节点到根节点的路径。搜索过程如下: 1. 如果当前节点为空,则返回。 2. 将当前节点的值添加到当前路径。 3. 将当前节点的值累加到当前路径的和。 4. 如果当前节点是叶子节点,且当前路径的和等于目标和,则将当前路径添加到结果。 5. 递归地搜索当前节点的左子树和右子树,并传递更新后的当前路径和当前路径的和。 最后,在主函数调用辅助函数,并返回结果即可。 以下是题目的完整代码实现: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def pathSum(root, target): def dfs(node, path, path_sum, target, res): if not node: return path.append(node.val) path_sum += node.val if not node.left and not node.right: # 当前节点是叶子节点 if path_sum == target: res.append(path[:]) # 注意需要复制一份path,否则会出现问题 dfs(node.left, path, path_sum, target, res) dfs(node.right, path, path_sum, target, res) path.pop() # 回溯到父节点,去掉当前节点 path_sum -= node.val res = [] dfs(root, [], 0, target, res) return res ``` 这样就能找出所有满足路径和等于目标和的路径了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值