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();
}
}
}