# Ternary operator confusion in Java.

go评论93阅读模式

Ternary operator confusion in Java

# 问题

``````我正在解决LeetCode 437路径总和 III问题https://leetcode.com/problems/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);
}
``````

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

TreeNode: [1,-2,-3,1,3,-2,null,-1], Sum: -1

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

I am doing LeetCode 437 Path Sum III https://leetcode.com/problems/path-sum-iii/
and my original code is as follows which passed all tests:

``````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);
}
``````

My confusion is from `int res = root.val == sum ? 1 : 0;` in the private method. When I tried to shorten my code, I deleted this line and changed the return value to

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

However, this change caused some tests to fail. For example,

> TreeNode: [1,-2,-3,1,3,-2,null,-1], Sum: -1

The correct output should be 4 but with this change the output is 3.

More surprisingly, when I change the order of addition, say put the ternary to the last:

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

the output is changed to 2.

I really had no idea what happened here. In my opinion, the order of addition should not matter the final result. I'm not very familiar with the ternary operator and I guess this issue might be due to the incorrect use? I searched a lot on the Internet but still couldn't find out the reason. Thanks for anyone's explanation.

# 答案1

> 在我看来

``````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);
``````

``````return (root.val == sum ? 1 : 0)
// ^-----------------------^ 额外的括号。
+ pathSumStartWithRoot(root.left, sum - root.val)
+ pathSumStartWithRoot(root.right, sum - root.val);
``````

> In my opinion

Unfortunately, your opinion isn't relevant to the compiler.

``````int a = condition ? 1 : 0;
int b = a + c;
``````

is equivalent to:

``````int b = (condition ? 1 : 0) + c;
``````

It's not equivalent to:

``````int b = condition ? 1 : 0 + c;
``````

because that's the same as:

``````int b = condition ? 1 : (0 + c);
``````

owing to `+` having higher precedence than `?:`. (See table of precedence of the operators).

So if you want to inline the conditional expression, you need to use parentheses to indicate the intended precedence.

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

# 答案2

``````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;
}
}
``````

## 参考资料

• 若要了解更多细节，您可以查看讨论板。那里有许多已接受的解决方案，涵盖了各种编程语言和解释，高效的算法，以及渐近的时间/空间复杂性分析<sup>12</sup>。

You should not even do that for interviews. That "shortening" code is irrelevant to algorithm design, and has nothing to do with efficiency (time or memory), I guess.

Another point is that [tag:java] and [tag:c++] are not designed for writing one liners.

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

private static final int helper(TreeNode node, int currSum, int target, HashMap&lt;Integer, Integer&gt; 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;
}
}
``````

## References

• For additional details, you can see the Discussion Board. There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time/space complexity analysis<sup>1, 2</sup> in there.

# 答案3

`+` 运算符的优先级高于三元运算符 `?:`，因此你的代码部分会首先执行加法操作，然后才是三元运算部分，如下所示：

``````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);
``````

`+` operator precedence is higher than ternary operator `?:` so you code

``````pathSumStartWithRoot(root.left, sum - root.val)
+ pathSumStartWithRoot(root.right, sum - root.val)+ root.val
``````

this addition part will works first then ternary part like

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

So you can use bracket for tenary portion

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

• 本文由 发表于 2020年7月23日 02:25:55
• 转载请务必保留本文链接：https://go.coder-hub.com/63040862.html
• conditional-operator
• java

go 78

go 87

go 63

go 53