【剑指offer】面试题34:二叉树中和为某一值的路径

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

 链接:https://www.nowcoder.com/questionTerminal/b736e784e3e34731af99065031301bca

由于 TreeNode 类中 node 节点没有指向其父节点的指针,所以需要将访问过的节点路径都保存下来。

当用前序遍历的方式访问到某一节点时,我们把该节点添加到路径上,并累加该节点的值。如果该结点为叶结点并且路径中结点值的和刚好为输入的整数,则当前的路径符合要求,我们把它打印出来。如果当前的结点不是叶结点,则继续访问它的子节点。当前结点访问结束后,递归函数将自动回到它的父节点。因此我们在函数退出之前要在路径上删除当前结点并减去当前结点的值,以确保返回父节点时路径刚好是从根节点到父节点的路径。我们不难看出保存路径的数据结构实际上是一个栈,因此路径要与递归调用状态一致,而递归调用的本质上是一个压栈和出栈的过程。

package com.zju.offer.tree;

import java.util.ArrayList;
import java.util.Arrays;

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

	public class TreeNode{
		private int val;
		private TreeNode left = null;
		private TreeNode right = null;
		
		public TreeNode(int val){
			this.val = val;
		}
	}
	// 所有符合条件路径的集合
	private ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>>();
	// 单条路径节点元素的的集合
	private ArrayList<Integer> list = new ArrayList<Integer>();
	 
	public ArrayList<ArrayList<Integer>> findPath(TreeNode root, int target){
		if(root == null){
			return null;
		}
		list.add(root.val);  // 先将根节点加入路径集合中
		target -= root.val;
		if(target == 0 && root.left == null && root.right == null){
			// target等于0,并且当前节点是叶子节点,则说明该路径符合条件
			listAll.add(new ArrayList<Integer>(list));
		}
		findPath(root.left, target);  // 左子树迭代查找
		findPath(root.right, target); // 右子树迭代查找
		// 如果当前路径已经到了叶子节点也不符合条件,则退回其父节点
		// 深度遍历完一条路径后要回退:将list中最后一个节点删除
		list.remove(list.size() - 1); 
		return listAll;
	}
	
	public static void main(String[] args) {
		
		FindPathEqualNum find = new FindPathEqualNum();
		
		TreeNode root = find.new TreeNode(10);
		TreeNode node1 = find.new TreeNode(5);
		TreeNode node2 = find.new TreeNode(12);
		TreeNode node3 = find.new TreeNode(4);
		TreeNode node4 = find.new TreeNode(7);
		
		root.left = node1;
		root.right = node2;
		
		node1.left = node3;
		node1.right = node4;
		
		ArrayList<ArrayList<Integer>> findPath = find.findPath(root, 22);
		System.out.println(Arrays.toString(findPath.toArray()));  // [[10, 5, 7], [10, 12]]
	}
}

猜你喜欢

转载自blog.csdn.net/pcwl1206/article/details/86084654