-1

I wrote this code, which passes all the test cases

//passes 1100/1100 cases
while (slow != null && slow.next != null && fast != null && fast.next != null) {
    fast = fast.next.next;
    slow = slow.next
}

On the other hand, this code does not, but seems to be very similar.

//passes 1/1100 cases
while (slow != null && slow.next != null && fast.next != null && fast != null) {
    fast = fast.next.next;
    slow = slow.next
}

I just noticed that just by changing the order of condition statements in while(), the number of test cases that pass changes. Why is it so?

Esther
  • 450
  • 3
  • 9
Dev
  • 1
  • 2
    please paste code as text, not images. see http://idownvotedbecau.se/imageofcode – Esther May 03 '22 at 17:51
  • If `fast == null` is true then access `fast.next` will throw NPE. So checking `fast.next` _before_ `fast == null` is a problem. See: [Short-circuit evaluation](https://en.wikipedia.org/wiki/Short-circuit_evaluation) – 001 May 03 '22 at 17:55
  • 1
    But please [edit] and add the code AS TEXT. [Why should I not upload images of code/data/errors when asking a question?](https://meta.stackoverflow.com/q/285551) – 001 May 03 '22 at 18:00
  • also see this https://stackoverflow.com/questions/42523442/does-order-of-conditions-matter-with-multiple-conditions-in-a-while-loop even though I already posted a better (imo) answer. – Esther May 03 '22 at 18:14

1 Answers1

2

Java if-statements use something called short-circuit evaluation, where if there is an && where the first condition is false, or an || where the first condition is true, then it will not evaluate the rest of the condition, because it already knows what the result will be. If there is an && and the first statement is false, then it doesn't matter what the rest of the statements evaluate to, since the whole thing is false, and vice-versa if there is an || and the first statement is true.

A second issue is that if an object is null, then calling any method or accessing any property of the function will throw a NullPointerException. This can be avoided by checking if an object is null before using it in cases where you know it might be null. In your linked list, evidently you are concerned that a node might be null, so you check before accessing its next.

These two combine together in your example. If you do

if (item != null && item.property != null) {}

and item is actually null, then because of short-circuit evaluation, Java will never actually check item.property to see if it's null as well, because it already knows the combined statement will be false.

Conversely, if you do

if (item.property != null && item != null) {}

then Java will try to access item.property, which will throw a NullPointerException if item is null.

In your case, evidently many of your test cases had situations where fast was null at some point. The example where they passed would have avoided calling fast.next when fast is null because of short-circuit evaluation, whereas the second example never avoids the NullPointerExceptions at all.

Esther
  • 450
  • 3
  • 9
  • Thank you so much for such a detailed explanation...... i really appreciate it. – Dev May 04 '22 at 18:48
  • @Dev if this answer helped you, you can click the green checkmark to mark the answer as "accepted" – Esther May 04 '22 at 18:53