剑指offer 34.二叉树中和为某一值的路径

剑指offer 34.二叉树中和为某一值的路径

题目描述

在这里插入图片描述

解题思路

注意和 leetcode 46. 全排列leetcode 78. 子集leetcode 77. 组合 回溯的区别,二者的选择列表是一样的,均为所有的孩子节点,主要区别在于路径的记录方式,本题是记录根节点,后者是记录孩子节点。

  • 上述的三道回溯题,每到一个节点面临多个选择时,如果做出其中一个选择,则路径中添加的是孩子节点的这个选择。因为根节点为空,初始是从根节点的孩子节点做选择。
    所以做选择和撤销选择的操作是在 for 循环里面,即每访问完一个孩子都需要撤销一次选择。这样遍历完后,唯独会忽略根节点的访问。

  • 而本题(包括其他的二叉树、图,以及 dp 的递归思路)做选择时,路径中添加的是当前正在做选择的节点
    所以做选择和撤销选择的操作是在 for 循环外面,即只需要访问完所有孩子后,撤销一次根节点的选择。这样遍历完后,会访问完整个树(包括根节点)。

完整代码:

class Solution {
    
    

     public List<List<Integer>> res = new LinkedList<>();

    public List<List<Integer>> pathSum(TreeNode root, int target) {
    
    
        if (root == null) return res;
        
        LinkedList<Integer> track = new LinkedList<>();
        backtrack(root, target, track);
        return res;
    }
    //定义:打印出从root节点一直到叶子节点的路径和为target的路径
    public void backtrack(TreeNode root, int target, LinkedList<Integer> track) {
    
    
        //空节点直接返回
        if (root == null) return;
        // 到达叶节点
        if (root.left == null && root.right == null && target == root.val) {
    
    
            track.add(root.val);
            res.add(new LinkedList<>(track));
            track.removeLast();
            return;
        }
        track.add(root.val);
        //在已将root添加进路径的基础上,分别打印出左右子树的路径
        backtrack(root.left, target - root.val, track);
        backtrack(root.right, target - root.val, track);

        track.removeLast();
    }
}

猜你喜欢

转载自blog.csdn.net/cys975900334/article/details/115180492
今日推荐