参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:二叉树中路径和为某一值
输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
主要思路:用前序遍历节点,若当前节点是叶子结点,且路径结点值的和等于所求值,则当前路径符合要求;若当前节点不是叶子结点,则继续遍历它的左右子节点。当前节点及其子节点遍历完后,要在路径中删除当前节点,使得递归状态重置到访问该节点之前(相等于回溯)。
关键点:递归,回溯
时间复杂度:O(n)
public class TreePathSum {
private static List<List<Integer>> allResults;
private static List<Integer> tempResult;
public static void main(String[] args) {
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
TreeNode root = TreeNode.generateBinaryTree();
allResults = new ArrayList<>();
tempResult = new ArrayList<>();
findPathSum(root, 20);
// [10, 6, 4]
for (List<Integer> integers : allResults) {
System.out.println(integers);
}
}
private static void findPathSum(TreeNode root, int target) {
if (root == null) {
return;
}
tempResult.add(root.val);
target -= root.val;
//路径和等于所求值,且当前节点是叶子节点
if (target == 0 && root.left == null && root.right == null) {
allResults.add(new ArrayList<>(tempResult));
}
//遍历子节点
findPathSum(root.left, target);
findPathSum(root.right, target);
//在路径中删除当前节点
tempResult.remove(tempResult.size() - 1);
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
/**
* 生成二叉搜索树
*
* @return
*/
public static TreeNode generateBinaryTree() {
TreeNode root = new TreeNode(10);
TreeNode node6 = new TreeNode(6);
TreeNode node14 = new TreeNode(14);
TreeNode node4 = new TreeNode(4);
TreeNode node8 = new TreeNode(8);
TreeNode node12 = new TreeNode(12);
TreeNode node16 = new TreeNode(16);
connectNode(root, node6, node14);
connectNode(node6, node4, node8);
connectNode(node14, node12, node16);
return root;
}
private static void connectNode(TreeNode root, TreeNode left, TreeNode right) {
root.left = left;
root.right = right;
}
}