-1

Working on a leetcode problem described as: "Given a binary array nums and an integer k, return the maximum number of consecutive 1's in the array if you can flip at most k 0's."

I am using a sliding window approach and had produced the below code:

class Solution {
    public int longestOnes(int[] nums, int k) {
        int current = 0;
        int left = 0;
        int ans = 0;
           
        for (int right = 0; right < nums.length; right++){
            if (nums[right] == 0){
                current++;
            }         
            
            while (current > k){
                if (nums[left] == 0){
                    current--;
                }
                left++;
            }

            ans = right - left + 1;    
        }
        return ans;
    }
}

This produces a logical error in the ouptut where the value returned is off by 1 in either direction depending on the test. I replaced the while loop with in if statement shown in the code below which fixed the error. Why is this the case?

class Solution {
    public int longestOnes(int[] nums, int k) {
        int current = 0;
        int left = 0;
        int ans = 0;
           
        for (int right = 0; right < nums.length; right++){
            if (nums[right] == 0){
                current++;
            }         
            
            if (current > k){
                if (nums[left] == 0){
                    current--;
                }
                left++;
            }
            ans = right - left + 1;    
        }
            
        return ans;
    }
}

I expected the while loop to run once and be equivalent as the block should evaluate the condition on each iteration and then act if the condition is true. What is happening here?

starball
  • 20,030
  • 7
  • 43
  • 238
Siggyweb
  • 15
  • 6
  • If `current` is 2, the while body will be executed twice. If it is three, it will be executed three times. With an `if` it is guaranteed to be only executed at most once. Not sure I get what your question is – a loop loops until the condition becomes false. – knittl Jan 15 '23 at 21:26
  • Please provide a runnable example which illustrates the problem. – tgdavies Jan 15 '23 at 21:30
  • 1
    And why not just put a breakpoint in your while loop and *find out* why it's running more than once? – tgdavies Jan 15 '23 at 21:31
  • 1
    if `nums[left]` isn't `0`, the `while` operates differently. You say the second snippet 'passes', but it's not correct. Example input: 01111111000000000000000110. You always overwrite the answer, some sort of `ans = Math.max()` or similar needs to be involved somewhere. – rzwitserloot Jan 15 '23 at 22:00
  • Thanks all good spot that the conditional logic when current overtakes k is dependent on the first number in the window being a 0, @rzwitserloot please could you elaborate on what you mean with the use of `ans = Math.max()`? – Siggyweb Jan 16 '23 at 08:54
  • Looks like you figured it out :) – rzwitserloot Jan 16 '23 at 12:22
  • Thank you kindly, it always looks so obvious when you find the answer :) – Siggyweb Jan 16 '23 at 21:17

1 Answers1

0

Solution moved from @SiggyWeb's question post:

Solution found via feedback from the comments

class Solution {
    public int longestOnes(int[] nums, int k) {
        int current = 0;
        int left = 0;
        int ans = 0;
           
        for (int right = 0; right < nums.length; right++){
            if (nums[right] == 0){
                current++;
            }         
            
            while (current > k){
                if (nums[left] == 0){
                    current--;
                }
                left++;
            }
            ans = Math.max(ans,right - left + 1);    
        }
        return ans;
    }
}
starball
  • 20,030
  • 7
  • 43
  • 238