zoukankan      html  css  js  c++  java
  • 剑指Offer对答如流系列

    面试题34:二叉树中和为某一值的路径

    题目描述

    输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

    比如说下面这棵树,输入二叉树和整数22,则打印出两条路径,一条是10 12 另一条是10 5 7
    在这里插入图片描述

    树的结构定义如下:

    public class Node{
            int e;
            Node left;
            Node right;
            Node(int x) { e = x; }
        }
    

    问题分析

    从上往下,找一条路径,由于是从根节点出发,我们选用前序遍历。

    如果我们找到了其中一条路径,达到叶节点后,由于没有指向父节点的引用,所以必须提前创建一个链表存储前面经过的节点。

    基于上面可以说,通过前序遍历,从根节点出发,每次在链表中存储遍历到的节点,若到达叶子节点,则根据所有节点的和是否等于输入的整数,判断是否打印输出。

    强调的这部分 可以变成 在每次遍历到一个节点时,令目标整数等于自己减去当前节点的值,若到达根节点时,最终的目标整数等于0就可以打印输出, 上面的是书上的,这里的是个人实现的。

    在当前节点访问结束后,我们需要返回到它的父节点,这个可以通过递归来实现,不过在函数一层一层返回之前要删除链表中的当前节点,以确保最终正确返回父节点。

    问题解答

      public void findPath(Node root, int target) {
            if(root==null) {
                return;
            }
            ArrayList<Integer> list= new ArrayList<>();
            printPath(root, target,list);
        }
    
        private void printPath(Node node,int target,ArrayList<Integer> list) {
            if(node==null) {
                return;
            }
            list.add(node.e);
            // 每个节点的target不会受到方法的影响而改变
            target -= node.e;
            // 叶子节点
            if(target==0 && node.left==null && node.right==null) {  
                for (Integer integer : list)
                    System.out.print(integer+" ");
                System.out.println();
            } else {     //中间节点
                printPath(node.left, target, list);
                printPath(node.right, target, list);
            }
            // 移除当前节点
            list.remove(list.size()-1);
        }
    
  • 相关阅读:
    汉字乱码、加密后结果字符串不一致
    msgpack和TParams互相转换
    unigui监听会话开始和结束
    System.JSON.Builders.pas
    保证最终一致性的模式
    使用 Delta Sharing 协议进行数据共享
    dremio 16 升级问题
    graylog 4.0 运行
    supabase 开源firebase 可选工具
    cube.js 最新playground 说明
  • 原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12246405.html
Copyright © 2011-2022 走看看