博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉树中和为某一值的路径
阅读量:4513 次
发布时间:2019-06-08

本文共 4564 字,大约阅读时间需要 15 分钟。

文章目录

题目描述

输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

public class Solution {
public ArrayList
> FindPath(TreeNode root,int target) {
}}

错误思路

image

错误代码

ArrayList
> lists = new ArrayList
>(); public ArrayList
> FindPath(TreeNode root,int target) { ArrayList
list = new ArrayList
(); if(root == null) return null; if(root.val <= target){ target = target - root.val; list.add(root.val); } while(root.left != null || root.right != null){ if(root.left != null){ FindPath(root.left,target); } if(root.right != null){ FindPath(root.right,target); } } if(target == 0) lists.add(list); return lists; } /** * 2493658== 2493658== 2493658== */

错误分析

只是想当然的按照人为的思想在分析,却没有一步一步根据实际情况进行分析,并且在遍历整个树的时候没有真正按照前序遍历的方式去分析,同时后来知道了节点重复的时候,也没有考虑到用一个辅助栈来表示路径。而是想当然的去重新还原root的值,而没有考虑到只需要把当前多余的子节点删掉即可

所以以后尽量一步一步先找到基本的方法,然后按照程序执行的步骤依次展现出来整个过程,从而发现其中的规律

正确思路

确定一个遍历方式:前序遍历(这里也只能前序遍历,因为必须先访问根节点,要从根节点出发)

步骤 访问 是否为子节点 队列 target
1 2 no 2 2
2 4 no 2,4 6
3 9 yes 2,4,9 15(加入lists)
4 4(重新回到根节点) no 2,4 6
5 3 no 2,4,3 9
6 6 yes 2,4,3,6 15(加入list)
7 3(重新回到根节点) no 2,4,3 9
8 7 yes 2,4,3,7 16
9 3(重新回到根节点) no 2,4,3 9
10 4(重新回到根节点) no 2,4 6
11 2(重新回到根节点) no 2 2
12 5 no 2,5 7
13 8 yes 2,5,8 15(加入list)
14 遍历结束

那么按照上面的思想我们再重新编辑代码:

import java.io.Serializable;import java.util.ArrayList;import java.util.Arrays;public class Test7 {
ArrayList
> lists = new ArrayList
>(); ArrayList
list = new ArrayList
(); public ArrayList
> FindPath(TreeNode root, int target) { if(root == null) return null; if(root.val <= target){ target = target - root.val; list.add(root.val); } if(root.left != null){ FindPath(root.left,target); } if(root.right != null){ FindPath(root.right,target); } if(target == 0){ ArrayList
listCopy = new ArrayList
(); listCopy.addAll(list); lists.add(listCopy); list.remove(list.size()-1); }else { if(list.size() > 1){ list.remove(list.size()-1); } } return lists; } public static void main(String[] args){ TreeNode root = new TreeNode(2); root.left = new TreeNode(4); root.right = new TreeNode(5); root.left.left = new TreeNode(9); root.left.right = new TreeNode(3); root.left.right.left = new TreeNode(6); root.left.right.right = new TreeNode(7); root.right.right = new TreeNode(8); Test7 t = new Test7(); ArrayList
> lists = t.FindPath(root,15); for(ArrayList
l : lists){ for(int i = 0; i < l.size(); i++){ System.out.print(l.get(i)); } System.out.println("=="); } } public static class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } }}

这个版本针对上面的二叉树是可以实现的,但是运行的时候发现,通过的运行测试为18.6%?,

根据提示又重新设计了一个测试用例,发现添加root的条件有问题,因为后面返回到根节点的时候不管target是否满足条件都是是一定会删除最后一个叶节点的,所以root的添加是不需要条件的,就相当于是访问一个就添加一个,这也符号前面表格里面的分析规则,分析好了居然没按照步骤来做?

下面的测试用例的二叉树如下

image

import java.io.Serializable;import java.util.ArrayList;import java.util.Arrays;public class Test7 {
ArrayList
> lists = new ArrayList
>(); ArrayList
list = new ArrayList
(); public ArrayList
> FindPath(TreeNode root, int target) { if(target == 0) return lists;//注意这里target为0是返回lists也就是一个空数组,而不是返回null if(root == null) return null; target = target - root.val;//删除添加root的条件 list.add(root.val); if(root.left != null){ FindPath(root.left,target); } if(root.right != null){ FindPath(root.right,target); } if( target == 0 && root.left == null && root.right == null){ ArrayList
listCopy = new ArrayList
(); listCopy.addAll(list); lists.add(listCopy); list.remove(list.size()-1); }else { if(list.size() > 1){ list.remove(list.size()-1); } } return lists; } public static void main(String[] args){ TreeNode root = new TreeNode(10); root.left = new TreeNode(5); root.right = new TreeNode(12); root.left.left = new TreeNode(4); root.left.right = new TreeNode(7);// root.left.right.left = new TreeNode(6);// root.left.right.right = new TreeNode(7);// root.right.right = new TreeNode(8); Test7 t = new Test7(); ArrayList
> lists = t.FindPath(root,15); for(ArrayList
l : lists){ for(int i = 0; i < l.size(); i++){ System.out.print(l.get(i)); } System.out.println("=="); } } public static class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } }}

同时还要注意root为null和target为null的特殊情况分别返回什么

转载于:https://www.cnblogs.com/flyingcr/p/10428287.html

你可能感兴趣的文章
[置顶] 怎么对待重复的代码
查看>>
多种方法实现H5网页图片动画效果;
查看>>
Ubuntu/CentOS下使用脚本自动安装 Docker
查看>>
源码解读Mybatis List列表In查询实现的注意事项
查看>>
POJ 2311 Cutting Game(二维SG+Multi-Nim)
查看>>
1978 Fibonacci数列 3
查看>>
1225 八数码难题
查看>>
C#控件的闪烁问题解决方法总结
查看>>
js 冒泡事件与解决冒泡事件
查看>>
2018-2019赛季多校联合新生训练赛第七场(2018/12/16)补题题解
查看>>
后台全选功能以及数据的提交方法
查看>>
Android 动画效果 及 自定义动画
查看>>
const与#define相比有什么不同?
查看>>
Eclipse4.7 SpringIDE插件的安装
查看>>
C#面向对象基础
查看>>
Jquery页面加载效果
查看>>
ios对new Date() 的兼容问题
查看>>
Charles常用设置
查看>>
filebeat
查看>>
如何在Bitmap中画图?(MFC)
查看>>