前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑指offer | 面试题27:二叉树中和为某一值的路径

剑指offer | 面试题27:二叉树中和为某一值的路径

作者头像
千羽
发布2021-12-29 13:24:15
1920
发布2021-12-29 13:24:15
举报
文章被收录于专栏:程序员千羽

死磕算法系列文章

  1. 干货 | 手撕十大经典排序算法
  2. 剑指offer | 认识面试
  3. 剑指offer | 面试题2:实现Singleton模式
  4. 剑指offer | 面试题3:二维数组的查找
  5. 剑指offer | 面试题4:替换空格
  6. 剑指offer | 面试题5:从尾到头打印链表
  7. 剑指offer | 面试题6:重建二叉树
  8. 剑指offer | 面试题7:用两个栈实现队列
  9. 剑指offer | 面试题8:旋转数组的最小数字
  10. 剑指offer | 面试题9:斐波那契数列
  11. 剑指offer | 面试题10:青蛙跳台阶问题
  12. 剑指offer | 面试题11:矩阵覆盖
  13. 剑指offer | 面试题12:二进制中1的个数
  14. 剑指offer | 面试题13:数值的整数次方
  15. 剑指offer | 面试题14:打印从1到最大的n位数
  16. 剑指offer | 面试题15:删除链表的节点
  17. 剑指offer | 面试题16:将数组中的奇数放在偶数前
  18. 剑指offer | 面试题17:链表中倒数第k个节点
  19. 剑指offer | 面试题18:反转链表
  20. 剑指offer | 面试题19:合并两个有序链表
  21. 剑指offer | 面试题20:判断二叉树A中是否包含子树B
  22. 剑指offer | 面试题21:二叉树的镜像
  23. 剑指offer | 面试题22:顺时针打印矩阵
  24. 剑指offer | 面试题23:包含min函数的栈
  25. 剑指offer | 面试题24:栈的压入、弹出序列
  26. 剑指offer | 面试题25:从上到下打印二叉树
  27. 剑指offer | 面试题26:二叉搜索树的后序遍历序列

Leetcode : https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof

GitHub : https://gitee.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_27_pathSum/Solution.java

剑指 Offer 27. 二叉树中和为某一值的路径

题目描述 :给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

难度:中等

叶子节点 是指没有子节点的节点。

示例 1:

代码语言:javascript
复制
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:

代码语言:javascript
复制
输入:root = [1,2,3], targetSum = 5
输出:[]

示例 3:

代码语言:javascript
复制
输入:root = [1,2], targetSum = 0
输出:[]

解题思路:

“本问题是典型的二叉树方案搜索问题,使用回溯法解决,其包含 先序遍历 + 路径记录 两部分。

  • 先序遍历: 按照 “根、左、右” 的顺序,遍历树的所有节点。
  • 路径记录: 在先序遍历中,记录从根节点到当前节点的路径。当路径为 ① 根节点到叶节点形成的路径 ② 各节点值的和等于目标值 sum 时,将此路径加入结果列表。

算法流程:pathSum(root,sum) 函数:

  • 初始化:结果列表res,路径列表 path.
  • 返回值:返回res即可。

recur (root, tar) 函数:

  • 递推参数:当前节点root,当前目标值tar 。
  • 终止条件:若节点root为空,则直接返回。
  • 递推工作:
    1. 路径更新:将当前节点值root. val加入路径path ;
    2. 目标值更新:tar=tar - root.val(即目标值tar从sum减至0);
    3. 路径记录:当①root为叶节点且②路径和等于目标值,则将此路径path加入res。
    4. 先序遍历:递归左1右子节点。
    5. 路径恢复:向上回溯前,需要将当前节点从路径path中删除,即执行path. pop()。
复杂度分析:
  • 时间复杂度 O(N): N 为二叉树的节点数,先序遍历需要遍历所有节点。
  • 空间复杂度 O(N): 最差情况下,即树退化为链表时,path 存储所有树节点,使用 O(N) 额外空间。
代码语言:javascript
复制
package com.nateshao.sword_offer.topic_27_pathSum;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @date Created by 邵桐杰 on 2021/12/1 16:45
 * @微信公众号 程序员千羽
 * @个人网站 www.nateshao.cn
 * @博客 https://nateshao.gitee.io
 * @GitHub https://github.com/nateshao
 * @Gitee https://gitee.com/nateshao
 * Description: 二叉树中和为某一值的路径
 */
public class Solution {

    public static void main(String[] args) {
        TreeNode node1 = new TreeNode(10);
        TreeNode node2 = new TreeNode(5);
        TreeNode node3 = new TreeNode(12);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(7);

        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;

        Solution p = new Solution();
        System.out.println(p.listAll);
        p.pathSum(node1, 22);
        for (List<Integer> list : p.listAll) {
            for (int i : list) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
        /**
         * []
         * 10 5 7
         * 10 12
         */
    }

    /****************************** 剑指offer **********************************/

    private static List<List<Integer>> listAll = new ArrayList<>();
    private static List<Integer> list = new ArrayList<>();

    /**
     * 思路:先保存根节点,然后分别递归在左右子树中找目标值,若找到即到达叶子节点,打印路径中的值
     *
     * @param root
     * @param target
     * @return
     */
    public static List<List<Integer>> pathSum(TreeNode root, int target) {
        if (root == null) return listAll;
        list.add(root.val);
        target -= root.val;
        if (target == 0 && root.left == null && root.right == null) {
            listAll.add(new ArrayList<>(list));
        }
        pathSum(root.left, target);
        pathSum(root.right, target);
        list.remove(list.size() - 1);
        return listAll;
    }


    /*********************** 精选解答 ***************************/
    LinkedList<List<Integer>> res = new LinkedList<>();
    LinkedList<Integer> path = new LinkedList<>();

    public List<List<Integer>> pathSum2(TreeNode root, int sum) {
        recur(root, sum);
        return res;
    }

    void recur(TreeNode root, int tar) {
        if (root == null) return;
        path.add(root.val);
        tar -= root.val;
        if (tar == 0 && root.left == null && root.right == null)
            res.add(new LinkedList(path));
        recur(root.left, tar);
        recur(root.right, tar);
        path.removeLast();
    }


    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 千羽的编程时光 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 剑指 Offer 27. 二叉树中和为某一值的路径
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档