当我尝试解决树问题时,"左叶的总和"在LeetCode OJ上,我观察到如下问题:
给定一个示例树,只有两个左侧离开节点为8和9,期望答案为17,完整树可以参考下面的主要方法。
我首先写的错误答案是使用静态成员变量" sum"存储当前递归的结果并作为参数传递到下一个递归。但是如下面的代码,它将始终返回0。
public class Solution {
public TreeNode root;
private static class TreeNode {
private String val;
private TreeNode left, right;
public TreeNode(String x) {
this.val = x;
}
}
public static int sum = 0;
public static int sumOfLeftLeaves(TreeNode root) {
if(root == null) {
return 0;
}
sumOfLeftLeavesRec(root, false, sum);
return sum;
}
public static void sumOfLeftLeavesRec(TreeNode x, boolean isLeft, int sum) {
if(x == null) {
return;
}
if(x.left == null && x.right == null && isLeft) {
sum += Integer.valueOf(x.val);
}
sumOfLeftLeavesRec(x.left, true, sum);
// As debug model check, if just use static memeber variable sum could not
// keep the value when return from deepest recursion, e.g when return from
// node 8, the sum should be 8 and pass into new recursion on node 6(which
// return from recursion of node 8), but real situation is sum will change
// back to 0.
sumOfLeftLeavesRec(x.right, false, sum);
}
public static void main(String[] args) {
/*
* The tree used for test
* 1
* / \
* 2 3
* / \ /
* 6 5 9
* /
* 8
*/
Solution s = new Solution();
s.root = new TreeNode("1");
s.root.left = new TreeNode("2");
s.root.right = new TreeNode("3");
s.root.left.left = new TreeNode("6");
s.root.left.right = new TreeNode("5");
s.root.left.left.left = new TreeNode("8");
s.root.right.left = new TreeNode("9");
int result = sumOfLeftLeaves(s.root);
System.out.println(result);
}
}
我在这个site第二个解决方案Java版本上观察到的正确答案。这产生了一个新的课程" Summ"并使用其成员变量" sum"存储并将结果传递给下一个递归,并且当我测试它工作正常(下面的代码)。主要方法和样本树是相同的。
public class Solution {
private class Accumulator{
int sum = 0;
}
public int sumOfLeftLeaves(TreeNode root) {
if(root == null) {
return 0;
}
Accumulator accumulator = new Accumulator();
sumOfLeftLeavesRec(root, false, accumulator);
return accumulator.sum;
}
/* Pass in a sum variable as an accumulator */
public void sumOfLeftLeavesRec(TreeNode x, boolean isLeft, Accumulator accumulator) {
if(x == null) {
return;
}
if(x.left == null && x.right == null && isLeft) {
accumulator.sum += x.val;
}
sumOfLeftLeavesRec(x.left, true, accumulator);
sumOfLeftLeavesRec(x.right, false, accumulator);
}
}
问题是为什么静态成员变量在这种情况下不起作用,为什么要创建一个新的嵌套类作为" Accumulator"可用于记录和传递"总和"结果成功了?从机制上讲,关键点是什么?感谢
答案 0 :(得分:1)
为什么静态成员变量不适用于递归方法中的保留值?
事实上,问题不在于sum
是静态的(虽然static sum
是一个坏主意......)
问题在于此代码:
public static void sumOfLeftLeavesRec(TreeNode x, boolean isLeft, int sum) {
if(x == null) {
return;
}
if(x.left == null && x.right == null && isLeft) {
sum += Integer.valueOf(x.val);
}
...
}
sum
变量不是静态的。这是一个局部变量。所以你正在做的是在每个sumOfLeftLeavesRec
调用结束时计算局部变量中的部分和然后将其丢弃。
您需要回到原始问题陈述,并弄清楚信息需要如何在递归调用之间流动。
提示:设计简单递归算法的 normal 方法是将信息作为调用参数传递,并将其作为调用结果返回。这应该在这里工作。
答案 1 :(得分:0)
在你的情况下,你创建整数变量sum它是原始的和不可变的。 您将此不可变变量作为参数传递,因此静态变量sum不会更新,因此请删除参数sum。 试试这个。
public class Solution {
public TreeNode root;
private static class TreeNode {
private String val;
private TreeNode left, right;
public TreeNode(String x) {
this.val = x;
}
}
public static int sum = 0;
public static int sumOfLeftLeaves(TreeNode root) {
if (root == null) {
return 0;
}
sumOfLeftLeavesRec(root, false);
return sum;
}
public static void sumOfLeftLeavesRec(TreeNode x, boolean isLeft) {
if (x == null) {
return;
}
if (x.left == null && x.right == null && isLeft) {
sum += Integer.valueOf(x.val);
}
sumOfLeftLeavesRec(x.left, true);
// As debug model check, if just use static memeber variable sum could not
// keep the value when return from deepest recursion, e.g when return from
// node 8, the sum should be 8 and pass into new recursion on node 6(which
// return from recursion of node 8), but real situation is sum will change
// back to 0.
sumOfLeftLeavesRec(x.right, false);
}
public static void main(String[] args) {
/*
* The tree used for test
* 1
* / \
* 2 3
* / \ /
* 6 5 9
* /
* 8
*/
Solution s = new Solution();
s.root = new TreeNode("1");
s.root.left = new TreeNode("2");
s.root.right = new TreeNode("3");
s.root.left.left = new TreeNode("6");
s.root.left.right = new TreeNode("5");
s.root.left.left.left = new TreeNode("8");
s.root.right.left = new TreeNode("9");
int result = sumOfLeftLeaves(s.root);
System.out.println(result);
}
}