剑指Offer-二叉树中和为某一路径(非递归、递归形式前序遍历)

import java.util.ArrayList;
import java.util.Stack;

import Sword2Offer.TreeNode;

class TreeRuleSum {
	/*
	 * path用来存储遍历路径 pathList用来存储满足条件的路径
	 */
	ArrayList<Integer> path = new ArrayList<Integer>();
	ArrayList<ArrayList<Integer>> pathList = new ArrayList<ArrayList<Integer>>();

	public ArrayList<ArrayList<Integer>> find(TreeNode root, int tartget) {
		if (root == null) {
			return pathList;
		}
		path.add(root.val);
		tartget -= root.val;
		if (tartget == 0 && root.left == null && root.right == null) {
			/**
			 * 必须要重新生成一个对象实例,并使用listNode对其进行初始化赋值,
			 * 不能直接listPath.add(listNode),因为listNode本质上是引用,
			 * 在各次遍历中会直接改变它的值,最后的路径集合中前面的路径也会被后面的覆盖。
			 */
			// pathList.add(path);
			pathList.add(new ArrayList<Integer>(path));
		}
		if (root.left != null) {
			find(root.left, tartget);
		}
		if (root.right != null) {
			find(root.right, tartget);
		}
		path.remove(path.size() - 1);
		return pathList;
	}
	
	/**
	 * 非递归的思路,前序遍历
	 * @param root
	 * @param tartget
	 * @return
	 */
	public ArrayList<ArrayList<Integer>> find2(TreeNode root, int tartget) {
		if(root==null) {
			return pathList;
		}
		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode lastNode;
		path.add(root.val);
		tartget -= root.val;
		stack.push(root);
		root = root.left;
		while(root!=null || !stack.isEmpty()) {
			/**
			 * 首先从根节点添加到最左端节点,将每一个节点的值添加进path中
			 */
			while(root!=null) {
				path.add(root.val);
				tartget -= root.val;
				stack.push(root);
				root = root.left;
			}
			/**
			 * 避免由于栈中弹出了对应元素,而该元素存在右节点,此时在弹出该元素的右节点之后需要将path跟stack一直,相当于清除操作
			 *     10
			 *    /  \
			 *   5    12
			 *  / \     
			 * 4   7
			 *  stack:10-->5-->4	path:10,5,4   此时stack弹出4,由于左右节点都为null,所以已经该条路径已经结束,path删除4
			 *  stack:10-->5		path:10,5	此时stack弹出5,由于5节点还存在子节点,所以不能在path中删除(留下了隐患)
			 *  stack:10-->7	path:10,5,7             满足条件(该条路径和为target,并且该条路劲上的最终节点是叶子结点)
			 *  stack:10		path:10,5		由于7节点子节点为空,弹出7节点;
			 *  	此时就需要擦屁股了,上次栈中弹出5,但是你又在path中未删除5,现在需要将path中的5清除
			 *  	stack.peek().val)!=(path.get(path.size()-1
			 *  stack:12		path:10	,12			弹出10,使得12入栈
			 *  最终将10-->5-->7  10-->12  添加进pathList中
			 *  
			 */
			while((stack.peek().val)!=(path.get(path.size()-1))){
				tartget += path.get(path.size()-1);
				path.remove(path.size()-1);
			}
			if(tartget==0 && stack.peek().left==null) {
				pathList.add(new ArrayList<Integer>(path));
			}
			/**
			 * 左节点到null之后,需要去找到右节点对应的元素,通过推栈来实现
			 */
			if(!stack.isEmpty()) {
				root = stack.pop();
				lastNode = root;
				root = root.right;
				if(root==null) {
					path.remove(path.size()-1);
					tartget += lastNode.val;
					
				}
			}
		}
		return pathList;
	}
	
}

public class TreeRuleSumEqualInteger {

	public static void main(String[] args) {
		TreeNode root = new TreeNode(10);
		TreeNode t1 = new TreeNode(5);
		TreeNode t2 = new TreeNode(12);
		TreeNode t3 = new TreeNode(4);
		TreeNode t4 = new TreeNode(7);
		root.left = t1;
		root.right = t2;
		t1.left = t3;
		t1.right = t4;
		TreeRuleSum tree = new TreeRuleSum();
//		ArrayList<ArrayList<Integer>> res = tree.find(root, 22);
		ArrayList<ArrayList<Integer>> res = tree.find2(root, 22);
		for (int i = 0; i < res.size(); i++) {
			for (int j = 0; j < res.get(i).size(); j++) {
				if (j != (res.get(i).size() - 1)) {
					System.out.print(res.get(i).get(j) + "--->");
				} else {
					System.out.print(res.get(i).get(j));
				}
			}
			System.out.println();
		}
	}

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值