以下是一个采访问题。
您将获得一个二叉树(不一定是BST),其中每个节点都包含一个值。设计一个算法来打印所有总计为该值的路径。注意,它可以是树中的任何路径-它不必从根开始。
虽然我能够找到树中从根开始的所有路径都有给定的总和,但对于不是从根开始的路径,我无法这样做。
基于上面Christian的回答:
public void printSums(Node n, int sum, int currentSum, String buffer) {
if (n == null) {
return;
}
int newSum = currentSum + n.val;
String newBuffer = buffer + " " + n.val;
if (newSum == sum) {
System.out.println(newBuffer);
}
printSums(n.left, sum, newSum, newBuffer);
printSums(n.right, sum, newSum, newBuffer);
printSums(n.left, sum, 0, "");
printSums(n.right, sum, 0, "");
}
printSums(root, targetSum, 0, "");
这里有一个O(n numResults)答案(基本上与@某人的答案相同,但所有问题都已解决):
累积量SumBeforeNode
。的哈希表中(该key的值将是节点列表)。
- 计算
umulativeSumBeforeNode
和目标总和之间的差异。在哈希表中查找此差异。 - 如果哈希表查找成功,它应该生成一个节点列表。这些节点中的每一个都代表解决方案的开始节点。当前节点代表每个相应开始节点的结束节点。将每个[开始节点,结束节点]组合添加到您的答案列表中。如果哈希表查找失败,则什么都不做。
- 在遍历中访问完一个节点后,从哈希表中存储在key
umulativeSumBeforeNode
的列表中删除该节点。
代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class BinaryTreePathsWithSum {
public static void main(String[] args) {
BinaryTreeNode a = new BinaryTreeNode(5);
BinaryTreeNode b = new BinaryTreeNode(16);
BinaryTreeNode c = new BinaryTreeNode(16);
BinaryTreeNode d = new BinaryTreeNode(4);
BinaryTreeNode e = new BinaryTreeNode(19);
BinaryTreeNode f = new BinaryTreeNode(2);
BinaryTreeNode g = new BinaryTreeNode(15);
BinaryTreeNode h = new BinaryTreeNode(91);
BinaryTreeNode i = new BinaryTreeNode(8);
BinaryTreeNode root = a;
a.left = b;
a.right = c;
b.right = e;
c.right = d;
e.left = f;
f.left = g;
f.right = h;
h.right = i;
/*
5
/ \
16 16
\ \
19 4
/
2
/ \
15 91
\
8
*/
List<BinaryTreePath> pathsWithSum = getBinaryTreePathsWithSum(root, 112); // 19 => 2 => 91
System.out.println(Arrays.toString(pathsWithSum.toArray()));
}
public static List<BinaryTreePath> getBinaryTreePathsWithSum(BinaryTreeNode root, int sum) {
if (root == null) {
throw new IllegalArgumentException("Must pass non-null binary tree!");
}
List<BinaryTreePath> paths = new ArrayList<BinaryTreePath>();
Map<Integer, List<BinaryTreeNode>> cumulativeSumMap = new HashMap<Integer, List<BinaryTreeNode>>();
populateBinaryTreePathsWithSum(root, 0, cumulativeSumMap, sum, paths);
return paths;
}
private static void populateBinaryTreePathsWithSum(BinaryTreeNode node, int cumulativeSumBeforeNode, Map<Integer, List<BinaryTreeNode>> cumulativeSumMap, int targetSum, List<BinaryTreePath> paths) {
if (node == null) {
return;
}
addToMap(cumulativeSumMap, cumulativeSumBeforeNode, node);
int cumulativeSumIncludingNode = cumulativeSumBeforeNode + node.value;
int sumToFind = cumulativeSumIncludingNode - targetSum;
if (cumulativeSumMap.containsKey(sumToFind)) {
List<BinaryTreeNode> candidatePathStartNodes = cumulativeSumMap.get(sumToFind);
for (BinaryTreeNode pathStartNode : candidatePathStartNodes) {
paths.add(new BinaryTreePath(pathStartNode, node));
}
}
populateBinaryTreePathsWithSum(node.left, cumulativeSumIncludingNode, cumulativeSumMap, targetSum, paths);
populateBinaryTreePathsWithSum(node.right, cumulativeSumIncludingNode, cumulativeSumMap, targetSum, paths);
removeFromMap(cumulativeSumMap, cumulativeSumBeforeNode);
}
private static void addToMap(Map<Integer, List<BinaryTreeNode>> cumulativeSumMap, int cumulativeSumBeforeNode, BinaryTreeNode node) {
if (cumulativeSumMap.containsKey(cumulativeSumBeforeNode)) {
List<BinaryTreeNode> nodes = cumulativeSumMap.get(cumulativeSumBeforeNode);
nodes.add(node);
} else {
List<BinaryTreeNode> nodes = new ArrayList<BinaryTreeNode>();
nodes.add(node);
cumulativeSumMap.put(cumulativeSumBeforeNode, nodes);
}
}
private static void removeFromMap(Map<Integer, List<BinaryTreeNode>> cumulativeSumMap, int cumulativeSumBeforeNode) {
List<BinaryTreeNode> nodes = cumulativeSumMap.get(cumulativeSumBeforeNode);
nodes.remove(nodes.size() - 1);
}
private static class BinaryTreeNode {
public int value;
public BinaryTreeNode left;
public BinaryTreeNode right;
public BinaryTreeNode(int value) {
this.value = value;
}
public String toString() {
return this.value + "";
}
public int hashCode() {
return Integer.valueOf(this.value).hashCode();
}
public boolean equals(Object other) {
return this == other;
}
}
private static class BinaryTreePath {
public BinaryTreeNode start;
public BinaryTreeNode end;
public BinaryTreePath(BinaryTreeNode start, BinaryTreeNode end) {
this.start = start;
this.end = end;
}
public String toString() {
return this.start + " to " + this.end;
}
}
}
这是一棵树,不是一个图。所以,你可以这样做:
伪代码:
global ResultList
function ProcessNode(CurrentNode, CurrentSum)
CurrentSum+=CurrentNode->Value
if (CurrentSum==SumYouAreLookingFor) AddNodeTo ResultList
for all Children of CurrentNode
ProcessNode(Child,CurrentSum)
好的,这给了你从根开始的路径。然而,你可以做一个小小的改变:
for all Children of CurrentNode
ProcessNode(Child,CurrentSum)
ProcessNode(Child,0)
你可能需要考虑一下(我正忙于其他事情),但这应该基本上运行植根于树中每个节点的相同算法
编辑:这实际上只给出了“结束节点”。但是,由于这是一棵树,您可以从这些结束节点开始,然后往后走,直到获得所需的总和。
编辑2:当然,如果所有值都为正,那么如果当前总和为,则可以中止下降
我试图打印二叉树的所有路径(根到叶的路径),但没有效果。 我的策略是使用递归,基本情况是树为None或树节点为leaf return,否则,遍历树的左侧和右侧。 但我找不到同时保留左右树的方法。
问题内容: 我试图使用Java在二叉树中打印所有根到叶的路径。 在主要方法中: 但是它给出了错误的输出。 给定的树: 预期产量: [5,1,3] [5、8、6] [5、8、9] 但是输出产生了: [5,1,3] [5、1、3、8、6] [5、1、3、8、6、9] 可以找出一个… 问题答案: 用以下方法调用递归方法: 传递时会发生什么(而不是在所有方法调用中使用单个对象,这意味着,当您返回原始调用者
本文向大家介绍Java实现打印二叉树所有路径的方法,包括了Java实现打印二叉树所有路径的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java实现打印二叉树所有路径的方法。分享给大家供大家参考,具体如下: 问题: 给一个二叉树,把所有的路径都打印出来。 比如,对于下面这个二叉树,它所有的路径为: 8 -> 3 -> 1 8 -> 2 -> 6 -> 4 8 -> 3 -> 6 ->
试图计算二叉树中从根到叶的路径和。似乎不起作用,doesIt的值变为true,但由于它是递归的,所以当堆栈弹出时,它会切换回false。我不知道怎么修。如何更改代码,使doesIt的值更改为true后,它会一直向上传播? 考虑树:[5,4,8,11, null, null, null,7,2]无序 5有两个孩子4和8,4有一个孩子11,8没有孩子 hasPathSum(根,22)
给定一棵二叉树,问题是找到所有根到叶的路径。我们通过以列表的形式传递路径,并在到达叶子时将其添加到结果中来了解算法。 我的问题是存储所有路径需要多少空间。我的直觉是,每条路径将消耗树高度(O(h))的内存顺序,如果我们的完整二叉树中有2*n-1个节点,那么每个节点对应于一条路径,因此假设树高度平衡,空间复杂度将为O(n*log(n))。我的分析正确吗?
我试图找到从根到叶的最小路径和,还需要计算最小路径。如果解决方案在左子树中,我的解决方案有效,但是如果结果在右子树中,根节点在结果路径中添加了两次,是否有人可以查看我的解决方案并帮助我修复此错误,如果有,还可以建议更好的运行时解决方案 我正在使用回溯访问所有节点,我认为我的解决方案的时间复杂度将是O(N)(因为所有节点都应该被访问,如果我错了,请纠正我)