5

I've been doing some algorithm questions and just saw a solution for a problem that is like this:

public int longestOnes(int[] nums, int k) {
  int windowStart = 0, windowEnd;
  for (windowEnd = 0; windowEnd < nums.length; ++windowEnd) {
    if (nums[windowEnd] == 0) k--;
    if (k < 0 && nums[windowStart++] == 0) k++;
  }
  return windowEnd - windowStart;
}

Specifically in the part where windowStart is incremented (nums[windowStart++]), I understand that it will first fetch the value from nums array using the current windowStart value and then it will be incremented.

However, I don't understand exactly when this piece of code will be executed. Only when k < 0?

If so, is it correct to write this code like below:

public int longestOnes(int[] nums, int k) {
  int windowStart = 0, windowEnd;
  for (windowEnd = 0; windowEnd < nums.length; ++windowEnd) {
    if (nums[windowEnd] == 0) k--;
    if (k < 0 && nums[windowStart] == 0) k++;
    if (k < 0) windowStart++;
  }
  return windowEnd - windowStart;
}

EDIT: I understand that in the third "if" k has been incremented and the condition is not gonna be the same. I'm just trying to wrap my head around it by writing that second "if" in a different way.

Somehow it seems to give me different results.

Would anyone know the difference and what exactly happens during that second condition (if (k < 0 && nums[windowStart] == 0) k++;)?

Bardo
  • 73
  • 4
  • 2
    Nope, it's not correct to write the code as shown in the second snippet, because the value of `k` can change. `k` could be less than zero in the first `if`, and equal to zero in the second `if`. – user3386109 Aug 10 '22 at 04:36
  • I understand... That was a bad example. But how would you rewrite that nums[windowStart++] in a more legible way though still the same logic. – Bardo Aug 10 '22 at 04:39
  • Your question is answered here: https://stackoverflow.com/questions/30297641/difference-between-prefix-and-postfix-operators-in-java – Cheng Thao Aug 10 '22 at 04:39
  • 1
    @ChengThao Not exactly. I understand the increment operator. But I couldn't get the right order of that specific execution. Thanks though. – Bardo Aug 10 '22 at 09:30

1 Answers1

5

Your rewrite produces different results because the second if you added is checking the new value of k, after it has been incremented in the previous line:

if (k < 0 && nums[windowStart] == 0) k++; // k is incremented here
if (k < 0) windowStart++; // then k is checked here

If k is -1 and nums[windowStart] == 0. k will change to 0 in the first line, and the k < 0 check in the second line will fail and windowStart++ will not run.

In the original version, there is only one k < 0 check, and windowStart++ is run if that check is true.

If you want to rewrite the code in a way that doesn't put windowStart++ inside the array index, you can do:

if (k < 0) {
    if(nums[windowStart] == 0) {
        k++;
    }
    windowStart++;
}

The idea is that k < 0 is the condition on which we do windowStart++, but the old value of windowStart before we increment it is used to access the array. And we only increment k if both k < 0 and nums[windowStart] == 0 are true.

Sweeper
  • 213,210
  • 22
  • 193
  • 313