**Difficulty:** Medium, **Asked-in:** Amazon, VMware.

**Key takeaway:** An excellent question to understand the idea of the sliding window. Using similar technique, we can solve several coding problems efficiently in O(n) time and O(1) space.

You are given an array of 1s and 0s, along with an integer k that represents the maximum number of allowed flips. Write a program to return the count of the maximum consecutive 1s in the array, considering that you can flip at most k 0s.

**Input:** X[] = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1], k = 2, **Output:** 8.

**Explanation:** We are allowed to flip a maximum of 2 zeroes. Flipping X[5] and X[7] results in 8 consecutive 1’s, which is the maximum possible under the given constraints.

**Input:** X[] = [1, 1, 0, 1, 0, 1, 0, 0, 1], k = 1, **Output:** 4.

**Explanation:** We are allowed to flip a maximum of 1 zero. Flipping X[2] gives us 4 consecutive 1's, which is the maximum possible under the given constraints.

- Brute force solution using nested loops
- Efficient solution using a sliding window technique

A brute-force solution idea is to consider every subarray through two nested loops. For each subarray, we count the number of zeroes and return the maximum-sized subarray with k or fewer zeroes.

```
int maxContinuousOnes(int X[], int n, int k)
{
int maxOneCount = 0;
for (int i = 0; i < n; i = i + 1)
{
int countZeros = 0;
int j = i;
while (j < n)
{
if (X[j] == 0)
{
countZeros = countZeros + 1;
if (countZeros > k)
break;
}
j = j + 1;
}
maxOneCount = max(maxOneCount, j - i);
}
return maxOneCount;
}
```

```
def max_continuous_ones(X, n, k):
max_one_count = 0
for i in range(n):
count_zeros = 0
j = i
while j < n:
if X[j] == 0:
count_zeros = count_zeros + 1
if count_zeros > k:
break
j = j +1
max_one_count = max(max_one_count, j - i)
return max_one_count
```

In the worst case, we will be exploring every subarray. For this, we are running two nested loops where for every value of i, j is going from i to n-1. Total no of loop iterations = n + n -1 + n-2 …+ 1 = n(n+1)/2 = O(n²). So time complexity = O(n²)*O(1) = O(n²).

We are only using a constant number of extra variables, so space complexity = O(1).

The critical question is: Can we improve the solution further and solve this problem using a single traversal of the array? Is there some insight into the problem that could help us build a better solution? Let's think! Considering there are only 0's and 1's in the array, two scenarios may arise:

- If the number of 0s is greater than k, then we need to track the maximum subarray size with k occurrences of zeroes.
- If the number of 0's is less than k, then the output will be the size of the array.

So the idea using the sliding window would be to track each window with k number of 0's and find the maximum size of such a window. How do we do this? Let's think!

The idea is to scan the array, track each window using two pointers, and count the 0s in each window. When the count of 0's is less than k, we keep moving forward in the current window by counting 0's and tracking the maximum number of 1 counts using a variable.

When the count of 0's is greater than k, we slide the left end of the current window by one forward. Before doing this, we need to update the zero count of the new window by checking whether the left end of the previous window is 0 or 1. If it is 0, then we decrement the zero count by 1.

**Step 1:** We initialize two variables, **zeroCount** and **maxOneCount**, to track the count of zeros in the current window and the maximum possible count of ones. zeroCount is initialized to 0, and maxOneCount is set to 0.

**Step 2:** We also initialize a pointer, **l = 0**, to track the left end of the current window and run a loop from **r = 0 to n - 1** to access each window. Note: In this loop, the pointer r tracks the right end of the current window.

- When X[r] equals 0, we increment zeroCount by 1.
- If zeroCount becomes greater than k, we slide the current window by incrementing the left pointer l. Before this, we check the left end of the previous window: if X[l] equals 0, then we update the zero count of the current window by decrementing zeroCount.
- At each step of the iteration, we keep track of the maximum possible 1 count, i.e.,
**maxOneCount = max(maxOneCount, r - l + 1).**

**Step 3:** By the end of the loop, we return the value stored in the variable maxOneCount.

```
int maxConsecutiveOne(int X[], int n, int k)
{
int zeroCount = 0;
int l = 0;
int maxOneCount = 0;
for (int r = 0; r < n; r = r + 1)
{
if (X[r] == 0)
zeroCount = zeroCount + 1;
if (zeroCount > k)
{
if (X[l] == 0)
zeroCount = zeroCount - 1;
l = l + 1;
}
maxOneCount = max(maxOneCount, r - l + 1);
}
return maxOneCount;
}
```

```
def max_consecutive_one(X, n, k):
zero_count = 0
l = 0
max_one_count = 0
for r in range(n):
if X[r] == 0:
zero_count = zero_count + 1
if zero_count > k:
if X[l] == 0:
zero_count = zero_count - 1
l = l + 1
max_one_count = max(max_one_count, r - l + 1)
return max_one_count
```

In the above code, we run a single loop and perform a constant number of operations at each iteration. So the time complexity = n * O(1) = O(n). As we use only a constant extra variables, the space complexity is O(1).

- How do we modify the above code when we need to return the indices of the maximum continuous series of 1s in order?
- There could be multiple possible solutions. How can we modify the above code to return the sequence with the minimum start index?
- Can we think of solving this problem using some other approaches?
- What would be the worst and best-case scenarios for the above approaches?
- Do both approaches handle scenarios when the number of 0's is less than k in the input?

- Count number of nice subarrays
- Replace the substring for balanced string
- Max consecutive ones
- Binary subarrays with sum
- Subarrays with K different integers
- Fruit into baskets
- Shortest subarray with sum at least K
- Minimum size subarray sum

**Enjoy learning, Enjoy coding!**