Java中的三元运算符混淆

Java中的三元运算符混淆,java,conditional-operator,c++,Java,Conditional Operator,C++,我在做LeetCode 437 Path Sum III 我的原始代码如下,通过了所有测试: public int pathSum(TreeNode root, int sum) { if (root == null) { return 0; } return pathSumStartWithRoot(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum

我在做LeetCode 437 Path Sum III 我的原始代码如下,通过了所有测试:

public int pathSum(TreeNode root, int sum) {
        if (root == null) {
            return 0;
        }
        return pathSumStartWithRoot(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
    }
    
    private int pathSumStartWithRoot(TreeNode root, int sum) {
        if (root == null) return 0;
        int res = root.val == sum ? 1 : 0;
        return res
            + pathSumStartWithRoot(root.left, sum - root.val) 
            + pathSumStartWithRoot(root.right, sum - root.val);
    }
我的困惑来自
int res=root.val==sum?1 : 0;在私有方法中。当我试图缩短代码时,我删除了这一行,并将返回值更改为

    return root.val == sum ? 1 : 0 
   + pathSumStartWithRoot(root.left, sum - root.val) + pathSumStartWithRoot(root.right, sum - root.val);
然而,这一变化导致一些测试失败。比如说,

树节点:[1,-2,-3,1,3,-2,null,-1],和:-1

正确的输出应为4,但通过此更改,输出为3

更令人惊讶的是,当我改变加法顺序时,比如说将三元数放在最后:

        return pathSumStartWithRoot(root.left, sum - root.val) 
        + pathSumStartWithRoot(root.right, sum - root.val)
        + root.val == sum ? 1 : 0;
输出更改为2

我真的不知道这里发生了什么。在我看来,加法的顺序不应该影响最终结果。我不太熟悉三元运算符,我想这个问题可能是由于使用不正确?我在网上搜索了很多,但仍然找不到原因。谢谢大家的解释

在我看来

不幸的是,您的意见与编译器无关

int a = condition ? 1 : 0;
int b = a + c;
相当于:

int b = (condition ? 1 : 0) + c;
int b = condition ? 1 : 0 + c;
这并不等于:

int b = (condition ? 1 : 0) + c;
int b = condition ? 1 : 0 + c;
因为这与:

int b = condition ? 1 : (0 + c);
由于
+
的优先级高于
?:
。()

因此,如果要内联条件表达式,则需要使用括号来指示预期的优先级

return (root.val == sum ? 1 : 0)
    // ^-----------------------^ Extra parens.
   + pathSumStartWithRoot(root.left, sum - root.val)
   + pathSumStartWithRoot(root.right, sum - root.val);

你甚至不应该在面试时这样做。我想,“缩短”代码与算法设计无关,与效率(时间或内存)无关

另一点是,和不是为编写一行程序而设计的

只要遵循惯例:

public class Solution {
    public final int pathSum(TreeNode root, int sum) {
        HashMap<Integer, Integer> prefixSum = new HashMap<>();
        prefixSum.put(0, 1);
        return helper(root, 0, sum, prefixSum);
    }

    private static final int helper(TreeNode node, int currSum, int target, HashMap<Integer, Integer> prefixSum) {
        if (node == null)
            return 0;

        currSum += node.val;
        int res = prefixSum.getOrDefault(currSum - target, 0);
        prefixSum.put(currSum, 1 + prefixSum.getOrDefault(currSum, 0));
        res += helper(node.left, currSum, target, prefixSum) + helper(node.right, currSum, target, prefixSum);
        prefixSum.put(currSum, prefixSum.get(currSum) - 1);
        return res;
    }
}
公共类解决方案{
公共最终整数路径和(树节点根,整数和){
HashMap prefixSum=新的HashMap();
前缀put(0,1);
返回帮助程序(根、0、和、前缀);
}
私有静态final int helper(TreeNode节点、int currSum、int target、HashMap前缀){
if(node==null)
返回0;
currSum+=node.val;
int res=prefixSum.getOrDefault(currSum-target,0);
prefixSum.put(currSum,1+prefixSum.getOrDefault(currSum,0));
res+=helper(node.left,currSum,target,prefixSum)+helper(node.right,currSum,target,prefixSum);
prefixSum.put(currSum,prefixSum.get(currSum)-1);
返回res;
}
}

工具书类
  • 有关其他详细信息,请参见。这里有很多公认的解决方案,有各种解释和解释,有高效的算法,还有渐近/复杂性分析

+
运算符优先级高于三元运算符
?:
所以您需要编码

pathSumStartWithRoot(root.left, sum - root.val) 
 + pathSumStartWithRoot(root.right, sum - root.val)+ root.val
这个加法部分将首先工作,然后像三元部分一样工作

return ((pathSumStartWithRoot(root.left, sum - root.val) 
        + pathSumStartWithRoot(root.right, sum - root.val)
        + root.val) == sum) ? 1 : 0;
所以你们可以用括号来表示十位数的部分

return pathSumStartWithRoot(root.left, sum - root.val) 
        + pathSumStartWithRoot(root.right, sum - root.val)
        + (root.val == sum ? 1 : 0);

Put
root.val==sum?1:0
()
中。您需要了解运算符优先级(以及为什么括号在某些情况下很重要)。我真的希望编程老师教正确使用括号。@nomaker或只是调试。调试器的使用应该在学生能够处理“Hello World”程序后立即教。