Maximum Consecutive Ones After Flipping Zeroes
Given a binary array arr[] and an integer k, find the maximum length of a subarray containing all ones after flipping at most k zeroes to 1's.
Examples:
Input: arr[] = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1], k = 2
Output: 8
Explanation: By flipping the zeroes at index 5 and 7, we get the longest subarray from index 3 to 10 containing all 1's.Input: arr[] = [1, 0, 0, 1, 0, 1, 0, 1], k = 2
Output: 5
Explanation: By flipping the zeroes at indices 4 and 6, we get the longest subarray from index 3 to 7 containing all 1's.
Table of Content
[Naive Approach] By Exploring All the Subarrays - O(n^2) Time and O(1) Space
A simple approach is to generate all possible subarrays using two nested loops. Then, for each subarray, count the number of zeroes. If the count is less than or equal to k, we can convert all the elements of the subarray to one by flipping all the zeroes. Finally, the length of longest subarray among all such subarrays will be our answer.
#include <vector>
using namespace std;
int maxOnes(vector<int> &arr, int k) {
int res = 0;
// Exploring all subarrays
for(int i = 0; i < arr.size(); i++) {
// Counter for zeroes
int cnt = 0;
for(int j = i; j < arr.size(); j++) {
if(arr[j] == 0)
cnt++;
// If cnt is less than or equal to k, then
// all zeroes can be flipped to one
if(cnt <= k)
res = max(res, (j - i + 1));
}
}
return res;
}
int main() {
vector<int> arr= {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
cout << maxOnes(arr, k);
return 0;
}
#include <stdio.h>
int maxOnes(int arr[], int n, int k) {
int res = 0;
// Exploring all subarrays
for(int i = 0; i < n; i++) {
// Counter for zeroes
int cnt = 0;
for(int j = i; j < n; j++) {
if(arr[j] == 0)
cnt++;
// If cnt is less than or equal to k, then
// all zeroes can be flipped to one
if(cnt <= k)
res = (res > (j - i + 1)) ? res : (j - i + 1);
}
}
return res;
}
int main() {
int arr[] = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", maxOnes(arr, n, k));
return 0;
}
class GfG {
static int maxOnes(int[] arr, int k) {
int res = 0;
// Exploring all subarrays
for(int i = 0; i < arr.length; i++) {
// Counter for zeroes
int cnt = 0;
for(int j = i; j < arr.length; j++) {
if(arr[j] == 0)
cnt++;
// If cnt is less than or equal to k, then
// all zeroes can be flipped to one
if(cnt <= k)
res = Math.max(res, (j - i + 1));
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
System.out.println(maxOnes(arr, k));
}
}
def maxOnes(arr, k):
res = 0
# Exploring all subarrays
for i in range(len(arr)):
# Counter for zeroes
cnt = 0
for j in range(i, len(arr)):
if arr[j] == 0:
cnt += 1
# If cnt is less than or equal to k, then
# all zeroes can be flipped to one
if cnt <= k:
res = max(res, j - i + 1)
return res
if __name__ == "__main__":
arr = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1]
k = 2
print(maxOnes(arr, k))
using System;
class GfG {
static int maxOnes(int[] arr, int k) {
int res = 0;
// Exploring all subarrays
for(int i = 0; i < arr.Length; i++) {
// Counter for zeroes
int cnt = 0;
for(int j = i; j < arr.Length; j++) {
if(arr[j] == 0)
cnt++;
// If cnt is less than or equal to k, then
// all zeroes can be flipped to one
if(cnt <= k)
res = Math.Max(res, (j - i + 1));
}
}
return res;
}
static void Main(string[] args) {
int[] arr = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
Console.WriteLine(maxOnes(arr, k));
}
}
function maxOnes(arr, k) {
let res = 0;
// Exploring all subarrays
for (let i = 0; i < arr.length; i++) {
// Counter for zeroes
let cnt = 0;
for (let j = i; j < arr.length; j++) {
if (arr[j] === 0)
cnt++;
// If cnt is less than or equal to k, then
// all zeroes can be flipped to one
if (cnt <= k)
res = Math.max(res, j - i + 1);
}
}
return res;
}
// Driver code
const arr = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1];
const k = 2;
console.log(maxOnes(arr, k));
Output
8
[Expected Approach] Using Sliding Window Technique - O(n) Time and O(1) Space
The idea is to use two pointers, start and end, to mark the start and end points of the current subarray (or window). Initially, both pointers are set at the beginning of the array. Continuously increase the size of the current window by incrementing the end pointer while keeping track of the count of zeros within the window. If at any point the count of zeros exceeds k, shrink the window by incrementing the start pointer until the count is reduced to k. The result will be the maximum length among all windows that contain at most k zeros.
#include <iostream>
#include <vector>
using namespace std;
int maxOnes(vector<int> &arr, int k) {
int res = 0;
// Start and end pointer of the window
int start = 0, end = 0;
// Counter to keep track of zeros in current window
int cnt = 0;
while (end < arr.size()) {
if (arr[end] == 0)
cnt++;
// Shrink the window from left if number of
// zeroes are greater than k
while (cnt > k) {
if (arr[start] == 0)
cnt--;
start++;
}
res = max(res, (end - start + 1));
// Increment end pointer to expand the window
end++;
}
return res;
}
int main() {
vector<int> arr = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
cout << maxOnes(arr, k);
return 0;
}
#include <stdio.h>
int maxOnes(int arr[], int n, int k) {
int res = 0;
// Start and end pointer of the window
int start = 0, end = 0;
// Counter to keep track of zeros in current window
int cnt = 0;
while (end < n) {
if (arr[end] == 0)
cnt++;
// Shrink the window from left if no.
// of zeroes are greater than k
while (cnt > k) {
if (arr[start] == 0)
cnt--;
start++;
}
res = (res > (end - start + 1)) ? res : (end - start + 1);
// Increment the end pointer to expand the window
end++;
}
return res;
}
int main() {
int arr[] = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", maxOnes(arr, n, k));
return 0;
}
class GfG {
static int maxOnes(int[] arr, int k) {
int res = 0;
// Start and end pointer of the window
int start = 0, end = 0;
// Counter to keep track of zeros in current window
int cnt = 0;
while (end < arr.length) {
if (arr[end] == 0)
cnt++;
// Shrink the window from left if
// no. of zeroes are greater than k
while (cnt > k) {
if (arr[start] == 0)
cnt--;
start++;
}
res = Math.max(res, (end - start + 1));
// Increment the end pointer to expand the window
end++;
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
System.out.println(maxOnes(arr, k));
}
}
def maxOnes(arr, k):
res = 0
# Start and end pointer of the window
start = 0
end = 0
# Counter to keep track of zeros in current window
cnt = 0
while end < len(arr):
if arr[end] == 0:
cnt += 1
# Shrink the window from left if no.
# of zeroes are greater than k
while cnt > k:
if arr[start] == 0:
cnt -= 1
start += 1
res = max(res, (end - start + 1))
# Increment the end pointer
# to expand the window
end += 1
return res
if __name__ == "__main__":
arr = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1]
k = 2
print(maxOnes(arr, k))
using System;
class GfG {
static int maxOnes(int[] arr, int k) {
int res = 0;
// Start and end pointer of the window
int start = 0, end = 0;
// Counter to keep track of zeroes
// in current window
int cnt = 0;
while (end < arr.Length) {
if (arr[end] == 0)
cnt++;
// Shrink the window from left if
// no. of zeroes are greater than k
while (cnt > k) {
if (arr[start] == 0)
cnt--;
start++;
}
res = Math.Max(res, (end - start + 1));
// Increment the end pointer to expand the window
end++;
}
return res;
}
static void Main(string[] args) {
int[] arr = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
int k = 2;
Console.WriteLine(maxOnes(arr, k));
}
}
function maxOnes(arr, k) {
let res = 0;
// Start and end pointer of the window
let start = 0;
let end = 0;
// Counter to keep track of zeroes
// in current window
let cnt = 0;
while (end < arr.length) {
if (arr[end] === 0)
cnt++;
// Shrink the window from left if
// no. of zeroes are greater than k
while (cnt > k) {
if (arr[start] === 0)
cnt--;
start++;
}
res = Math.max(res, (end - start + 1));
// Increment the end pointer to expand the window
end++;
}
return res;
}
// Driver Code
const arr = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1];
const k = 2;
console.log(maxOnes(arr, k));
Output
8