【面试题】在二元树中找出和为某一值的所有路径——Java实现

题目:

输入一个整数和一棵二元树。 从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。 打印出和与输入整数相等的所有路径。 例如输入整数22 和如下二元树

          10
        / \
       5  12
      / \
     4   7

则打印出两条路径:10, 12 和10, 5, 7。

思路:

1、每经过一个节点,将总和减去该节点的值作为下一次递归的总和值;

2、若当前节点为叶子节点,则判断此时的总和值是否已为零,为零则说明此条路径为正确路径;

3、若当前节点还有左或右孩子,则继续递归;

4、路径的存储(即目前走过的路径节点)使用数组存储,这里使用ArrayList。

代码如下:

public class TreeSumRoute {

	public static class Node{
		private int value;
		private Node leftNode;
		private Node rightNode;
		public Node(int value, Node leftNode, Node rightNode){
			this.value = value;
			this.leftNode = leftNode;
			this.rightNode = rightNode;
		}
	}
	
	/**
	 * 查找等于和值的路径,采用递归调用
	 * 每遇到一个节点,将该节点的值放入数组列表中,同时将所需和值减去刚进入列表的值作为新和值
	 * 如果下一级没有左右孩子,则说明此节点为叶子节点,如果此时和值恰好为零,打印path;如果不为零,说明此路径不正确,应删除path中不可用节点
	 * 如果下一级有左或右孩子,则继续递归调用
	 * @param node
	 * 当前所要经过的节点
	 * @param sum
	 * 经过当前节点前的和值
	 * @param path
	 * 当前的路径
	 */
	private void findRoute(Node node, int sum, ArrayList<Integer> path){
		path.add(node.value);
		sum -= node.value;
		if(node.leftNode == null&&node.rightNode == null){
			if(sum == 0){
				printPath(path);
			}
		}else{
			if(node.leftNode!=null){
				findRoute(node.leftNode, sum, path);
			}
			if(node.rightNode!=null){
				findRoute(node.rightNode, sum, path);
			}
		}
		//这里remove掉最后的元素是由于运行到这里说明没有匹配成功,则应去除最后的节点
		path.remove(path.size()-1);
	}
	
	/**
	 * 打印路径上的节点值
	 * @param path
	 * 走过的节点形成的路径,arraylist类型
	 */
	private void printPath(ArrayList<Integer> path) {
		for(int i=0; i<path.size(); i++){
			System.out.print(path.get(i)+" ");
		}
		System.out.println();
	}
	
	private void getRoute(Node node, int sum){
		ArrayList<Integer> path = new ArrayList<Integer>();
		findRoute(node, sum, path);
	}

	public static void main(String[] args) {
		Node node4 = new Node(4,null,null);
		Node node5 = new Node(7,null,null);
		Node node2 = new Node(5,node4,node5);
		Node node3 = new Node(12,null,null);
		Node node1 = new Node(10,node2,node3);
		TreeSumRoute tsr = new TreeSumRoute();
		tsr.getRoute(node1, 22);
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值