我正在解决问题https://leetcode.com/problems/path-sum-iii/ 我在这里也简要提一下: 查找二叉树中sum = sum的路径数。该路径不一定必须在根(叶)处开始(结束)。只要路径向下,就应该将其视为有效路径。
这是我的解决方案:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int pathSum(TreeNode root, int sum) {
int path = 0;
if(root.val == sum)
return 1;
else if(root.left == null && root.right == null)
return 0;
if(root.left != null){
path += pathSum(root.left, sum - root.val);
path += pathSum(root.left, sum);
}
if(root.right != null){
path += pathSum(root.right, sum - root.val);
path += pathSum(root.right, sum);
}
return path;
}
}
根据他们的系统的答案是3,但我得到以下输入的答案为4:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
我花了好几个小时试图解释为什么我的代码不起作用,但我无法弄清楚问题。
抱歉一个天真的问题:(但这是杀了我!
答案 0 :(得分:5)
我不确定你的解决方案有什么问题,但我认为这不对。首先,如果你的root是8,你会立即返回并只计算根作为解决方案。我就是这样做的:
GenericRepository
这个想法是在递归遍历树时沿着路径填充aarray的值,确保在返回时删除元素。当您访问节点时,您必须考虑从该节点到根路径上的任何节点的所有总和。其中任何一个都可以累加到您的参考值。当你遍历n个节点时,这个实现是O(nlogn),并且每个遍历一个len的数组遍历log(n)。
答案 1 :(得分:1)
您的代码无法满足此约束:
these nodes should be continuous.
例如此树的 root (值10)和此树的 leaf (值-2),它们的总和等于8. 但它不能满足连续性,所以它无法计数。
很遗憾,您的代码无法过滤此情况。
另一种解决方案:
public class Solution {
public int pathSum(TreeNode root, int sum) {
int path = traverse(root,sum);
return path;
}
public int traverse(TreeNode root, int sum){
int path = 0;
if(root==null){
return 0;
}
else{
path += calcu(root,sum);
path += traverse(root.left,sum);
path += traverse(root.right,sum);
return path;
}
}
private int calcu(TreeNode root, int sum) {
if(root==null){
return 0;
}
else if(root.val==sum){
return 1 + calcu(root.left,sum-root.val)+calcu(root.right,sum-root.val);
}
else{
return calcu(root.left,sum-root.val)+calcu(root.right,sum-root.val);
}
}
}
解释:traverse
这个树并将每个treeNode作为根节点,在前提下找到目标路径。
答案 2 :(得分:0)
您的解决方案的问题在于它还在计算10 - 2 = 8.其中10
是最顶层的根节点,-2
是底部叶子。它忽略了两者之间的所有路径。
我设法用tamperedSum
布尔值来解决它。
public static int pathSum(TreeNode root, int sum, boolean tamperedSum)
{
int path = 0;
if(root.val == sum)
path = 1;
if(root.left == null && root.right == null)
return path;
if(root.left != null){
path += pathSum(root.left, sum - root.val, true);
if (!tamperedSum)
path += pathSum(root.left, sum, false);
}
if(root.right != null){
path += pathSum(root.right, sum - root.val, true);
if (!tamperedSum)
path += pathSum(root.right, sum, false);
}
return path;
}
当我们从原始总和(在这种情况下是8)中扣除(节点的)值时,tamperedSum
布尔值设置为true。
我们将其调用为:
pathSum(root, sum, false)
这个想法是,如果总和已被<篡改,即路径上的节点值已被扣除,我们将不再允许将其按原样传递给节点下方的分支。
因此,每当我们从总和中扣除节点值时,我们就会将tamperedSum
设置为true
:sum - root.value
。之后,不允许其下面的所有节点通过sum
而不从中扣除其节点值。
答案 3 :(得分:0)
您的解决方案的问题在于,如果您处于新的内部路径,则不会从初始总和开始。
因此,当您移动内部路径时,您应该跟踪住宿金额和原始金额。
在下面找到您的算法的修改副本。
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
boolean visitedAsRoot = false;
TreeNode(int x) {
val = x;
}
}
public static int pathSum(TreeNode root, int accomulate, int sum) {
int path = 0;
if (root.val == accomulate)
return 1;
else if (root.left == null && root.right == null)
return 0;
if (root.left != null) {
path += pathSum(root.left, accomulate - root.val, sum);
if (!root.left.visitedAsRoot) {
root.left.visitedAsRoot = true;
path += pathSum(root.left, sum, sum);
}
}
if (root.right != null) {
path += pathSum(root.right, accomulate - root.val, sum);
if (!root.right.visitedAsRoot) {
root.right.visitedAsRoot = true;
path += pathSum(root.right, sum, sum);
}
}
return path;
}
public static void main(String args[]) {
TreeNode t1 = new TreeNode(3);
TreeNode t2 = new TreeNode(-2);
TreeNode t3 = new TreeNode(1);
TreeNode t4 = new TreeNode(3);
TreeNode t5 = new TreeNode(2);
TreeNode t6 = new TreeNode(11);
TreeNode t7 = new TreeNode(5);
TreeNode t8 = new TreeNode(-3);
TreeNode t9 = new TreeNode(10);
t4.left = t1;
t4.right = t2;
t5.right = t3;
t7.left = t4;
t7.right = t5;
t8.right = t6;
t9.left = t7;
t9.right = t8;
System.out.println(pathSum(t9, 8, 8));
}