Given a binary array arr[] consisting of 0's and 1's, a flip operation changes all 0's to 1's and 1's to 0's in a chosen subarray (l, r) where 0 ≤ l ≤ r < n. Find the maximum number of 1's after performing at most one flip.
Examples:
Input : arr[] = [0, 1, 0, 0, 1, 1, 0]
Output : 5
Explanation: Flip the subarray from index 2 to 3. Array will become [0, 1, 1, 1, 1, 1, 0]. Number of 1's will be 5.Input : arr[] = [0, 0, 0, 1, 0, 1]
Output : 5
Explanation: Flip the subarray from index 0 to 2. Array will become [1, 1, 1, 1, 0, 1]. Number of 1's will be 5.Input : arr[] = [0, 0, 0, 0]
Output: 4
Explanation: Flip the complete array.
Table of Content
[Naive Approach] Using Two Nested Loops - O(n^2) time and O(1) space
The idea is to count the original number of 1's in the array, then consider every possible subarray that could be flipped. For each potential subarray, we calculate how the flip would affect the total count of 1's by subtracting the number of 1's in the subarray (which would become 0's after flipping) and adding the number of 0's in the subarray (which would become 1's after flipping).
#include <iostream>
#include <vector>
using namespace std;
int maxOnes(vector<int> &arr) {
int n = arr.size();
int oneCnt = 0;
for (int i=0; i<n; i++) {
if (arr[i] == 1) oneCnt++;
}
int ans = oneCnt;
// Starting index of each subarray
for (int i=0; i<n; i++) {
int cnt = oneCnt;
// Ending index of each subarray
for (int j=i; j<n; j++) {
// If we flip the values, 1's
// count will also change.
if (arr[j] == 1) cnt--;
else cnt++;
// Compare with maximum answer
ans = max(ans, cnt);
}
}
return ans;
}
int main() {
vector<int> arr = {0, 1, 0, 0, 1, 1, 0};
cout << maxOnes(arr);
return 0;
}
class GfG {
static int maxOnes(int[] arr) {
int n = arr.length;
int oneCnt = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 1) oneCnt++;
}
int ans = oneCnt;
// Starting index of each subarray
for (int i = 0; i < n; i++) {
int cnt = oneCnt;
// Ending index of each subarray
for (int j = i; j < n; j++) {
// If we flip the values, 1's
// count will also change.
if (arr[j] == 1) cnt--;
else cnt++;
// Compare with maximum answer
ans = Math.max(ans, cnt);
}
}
return ans;
}
public static void main(String[] args) {
int[] arr = {0, 1, 0, 0, 1, 1, 0};
System.out.println(maxOnes(arr));
}
}
def maxOnes(arr):
n = len(arr)
oneCnt = 0
for i in range(n):
if arr[i] == 1:
oneCnt += 1
ans = oneCnt
# Starting index of each subarray
for i in range(n):
cnt = oneCnt
# Ending index of each subarray
for j in range(i, n):
# If we flip the values, 1's
# count will also change.
if arr[j] == 1:
cnt -= 1
else:
cnt += 1
# Compare with maximum answer
ans = max(ans, cnt)
return ans
if __name__ == "__main__":
arr = [0, 1, 0, 0, 1, 1, 0]
print(maxOnes(arr))
using System;
class GfG {
static int maxOnes(int[] arr)
{
int n = arr.Length;
int oneCnt = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 1)
oneCnt++;
}
int ans = oneCnt;
// Starting index of each subarray
for (int i = 0; i < n; i++) {
int cnt = oneCnt;
// Ending index of each subarray
for (int j = i; j < n; j++) {
// If we flip the values, 1's
// count will also change.
if (arr[j] == 1)
cnt--;
else
cnt++;
// Compare with maximum answer
ans = Math.Max(ans, cnt);
}
}
return ans;
}
static void Main()
{
int[] arr = { 0, 1, 0, 0, 1, 1, 0 };
Console.WriteLine(maxOnes(arr));
}
}
function maxOnes(arr) {
let n = arr.length;
let oneCnt = 0;
for (let i = 0; i < n; i++) {
if (arr[i] === 1) oneCnt++;
}
let ans = oneCnt;
// Starting index of each subarray
for (let i = 0; i < n; i++) {
let cnt = oneCnt;
// Ending index of each subarray
for (let j = i; j < n; j++) {
// If we flip the values, 1's
// count will also change.
if (arr[j] === 1) cnt--;
else cnt++;
// Compare with maximum answer
ans = Math.max(ans, cnt);
}
}
return ans;
}
let arr = [0, 1, 0, 0, 1, 1, 0];
console.log(maxOnes(arr));
Output
5
[Expected Approach] Using Modified Kadane's Algorithm - O(n) time and O(1) space
The idea is to transform the problem into a maximum subarray sum problem that can be solved with Kadane's algorithm. To do this, modify the array as follows:
Replace every 1 with -1 (since flipping it decreases the count of 1's)
Replace every 0 with +1 (since flipping it increases the count of 1's)After this transformation, the sum of any subarray represents the net gain in number of 1's after flipping that subarray. Now, apply Kadane's Algorithm to find the maximum subarray sum. This value gives the maximum possible gain in 1's. Finally, add this gain to the original count of 1's to get the maximum number of 1's achievable after at most one flip.
Conside the Array: [0, 1, 0, 0, 1, 1, 0]
Step 1: Count how many 1's are already present. Count= 3
Step 2: We convert the array like this:
- 0 to +1 (because flipping it gives a 1)
- 1 to -1 (because flipping it gives a 0)
- So the array becomes: [1, -1, 1, 1, -1, -1, 1]
Step 3: Apply Kadane’s Algorithm
Initialize sum = 0, maxSum = 0
Traverse array:
- Add 1 → sum = 1, maxSum = 1
- Add -1 → sum = 0
- Add 1 → sum = 1
- Add 1 → sum = 2, maxSum = 2
- Add -1 → sum = 1
- Add -1 → sum = 0
- Add 1 → sum = 1
Maximum subarray sum = 2. This 2 means we can gain 2 extra 1's by flipping some subarray.
Step 4: Original 1's = 3 , Extra gained = 2. Total maximum 1's = 3 + 2 = 5
#include <iostream>
#include <vector>
using namespace std;
// Function to find the maximum sum
// sub array.
int maxSumSub(vector<int> &arr) {
int n = arr.size();
int sum = 0;
int ans = 0;
for (int i=0; i<n; i++) {
sum += arr[i];
ans = max(ans, sum);
// If subarray sum becomes negative
// skip the subarray
if (sum < 0) sum = 0;
}
return ans;
}
// Main function to find the maximum number
// of 1's by flipping a subarray.
int maxOnes(vector<int> &arr) {
int n = arr.size();
int oneCnt = 0;
// Set 1's to -1 and 0's to 1
for (int i=0; i<n; i++) {
if (arr[i] == 1) {
arr[i] = -1;
oneCnt++;
}
else arr[i] = 1;
}
// Apply kadane's algorithm to find
// the number of extra 1's
int maxDiff = maxSumSub(arr);
// Return total 1's + flipped ones.
return oneCnt + maxDiff;
}
int main() {
vector<int> arr = {0, 1, 0, 0, 1, 1, 0};
cout << maxOnes(arr);
return 0;
}
class GfG {
// Function to find the maximum sum
// sub array.
static int maxSumSub(int[] arr) {
int n = arr.length;
int sum = 0;
int ans = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
ans = Math.max(ans, sum);
// If subarray sum becomes negative
// skip the subarray
if (sum < 0) sum = 0;
}
return ans;
}
// Main function to find the maximum number
// of 1's by flipping a subarray.
static int maxOnes(int[] arr) {
int n = arr.length;
int oneCnt = 0;
// Set 1's to -1 and 0's to 1
for (int i = 0; i < n; i++) {
if (arr[i] == 1) {
arr[i] = -1;
oneCnt++;
} else arr[i] = 1;
}
// Apply kadane's algorithm to find
// the number of extra 1's
int maxDiff = maxSumSub(arr);
// Return total 1's + flipped ones.
return oneCnt + maxDiff;
}
public static void main(String[] args) {
int[] arr = {0, 1, 0, 0, 1, 1, 0};
System.out.println(maxOnes(arr));
}
}
# Function to find the maximum sum
# sub array.
def maxSumSub(arr):
n = len(arr)
sum = 0
ans = 0
for i in range(n):
sum += arr[i]
ans = max(ans, sum)
# If subarray sum becomes negative
# skip the subarray
if sum < 0:
sum = 0
return ans
# Main function to find the maximum number
# of 1's by flipping a subarray.
def maxOnes(arr):
n = len(arr)
oneCnt = 0
# Set 1's to -1 and 0's to 1
for i in range(n):
if arr[i] == 1:
arr[i] = -1
oneCnt += 1
else:
arr[i] = 1
# Apply kadane's algorithm to find
# the number of extra 1's
maxDiff = maxSumSub(arr)
# Return total 1's + flipped ones.
return oneCnt + maxDiff
if __name__ == "__main__":
arr = [0, 1, 0, 0, 1, 1, 0]
print(maxOnes(arr))
using System;
class GfG {
// Function to find the maximum sum
// sub array.
static int maxSumSub(int[] arr) {
int n = arr.Length;
int sum = 0;
int ans = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
ans = Math.Max(ans, sum);
// If subarray sum becomes negative
// skip the subarray
if (sum < 0) sum = 0;
}
return ans;
}
// Main function to find the maximum number
// of 1's by flipping a subarray.
static int maxOnes(int[] arr) {
int n = arr.Length;
int oneCnt = 0;
// Set 1's to -1 and 0's to 1
for (int i = 0; i < n; i++) {
if (arr[i] == 1) {
arr[i] = -1;
oneCnt++;
} else arr[i] = 1;
}
// Apply kadane's algorithm to find
// the number of extra 1's
int maxDiff = maxSumSub(arr);
// Return total 1's + flipped ones.
return oneCnt + maxDiff;
}
static void Main() {
int[] arr = {0, 1, 0, 0, 1, 1, 0};
Console.WriteLine(maxOnes(arr));
}
}
// Function to find the maximum sum
// sub array.
function maxSumSub(arr) {
let n = arr.length;
let sum = 0;
let ans = 0;
for (let i = 0; i < n; i++) {
sum += arr[i];
ans = Math.max(ans, sum);
// If subarray sum becomes negative
// skip the subarray
if (sum < 0) sum = 0;
}
return ans;
}
// Main function to find the maximum number
// of 1's by flipping a subarray.
function maxOnes(arr) {
let n = arr.length;
let oneCnt = 0;
// Set 1's to -1 and 0's to 1
for (let i = 0; i < n; i++) {
if (arr[i] === 1) {
arr[i] = -1;
oneCnt++;
} else arr[i] = 1;
}
// Apply kadane's algorithm to find
// the number of extra 1's
let maxDiff = maxSumSub(arr);
// Return total 1's + flipped ones.
return oneCnt + maxDiff;
}
let arr = [0, 1, 0, 0, 1, 1, 0];
console.log(maxOnes(arr));
Output
5