Maximize sum of assigned weights by flipping at most K bits in given Binary String
Given a binary string str of length N and an integer K, the task is to find the maximum possible sum of assigned weights that can be obtained by flipping at most K bits in the given binary string. The weight assigned to the characters of this string are as follows:
- If a character is ‘0’, then the weight is 0.
- If a character is ‘1’ and the character preceding it is also ‘1’, then the weight is 2.
- If a character is ‘1’ and there is no character before it or the character preceding it is ‘0’, then the weight is 1.
Examples:
Input: str = “10100”, K = 2
Output: 7
Explanation:
1st flip: Flip the character at index 1, the string becomes “11100”.
2nd flip: Flip the character at index 3, the string becomes “11110”.
The weight of the resulting string is 1 + 2 + 2 + 2 + 0 = 7, which is maximum.
Input: str = “100101”, K = 1
Output: 6
Explanation:
1st flip: Flip the character at index 5, the string becomes “100111”.
The weight of the resulting string is 1 + 0 + 0 + 1 + 2 + 2 = 6, which is maximum.
Approach: The weight of character ‘1’ appearing after a ‘1’ is greatest among all characters, so to maximize the sum, try to create as many such 1s possible. The segments of 0s to be flipped to 1 can be prioritized as follows:
- First priority: Flip all 0s enclosed between two 1s, this would increase the weight of the segment of form 10…01 by (2*(number of 0s enclosed) + 1). If x is greater than or equal to the number of 0s enclosed otherwise by 2*(number of 0s enclosed).
- Second priority” Flip 0s at the beginning of the string preceding the first occurrence of 1s in the string, this would increase the weight of segment of form 0…01 by 2*(number of flipped 0s).
- Third priority: Flip 0s at the end of the string succeeding the last occurrence of 1 in the string, this would increase the weight of the segment of form 10…0 by 2*(number of flipped 0s).
Flip the character of the given string as per the above priority to maximize the weight and then find the weight of the resulting string after at most K flips.
Below is the implementation of this approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findMax(string s, int n, int k)
{
int ans = 0;
int l = 0;
int ind = -1;
int indf = -1;
multiset< int > ls;
for ( int i = 0; i < n; i++) {
if (s[i] == '0' )
l++;
else if (s[i] == '1'
&& l > 0 && ans != 0) {
ls.insert(l);
l = 0;
}
if (s[i] == '1' ) {
ind = i;
l = 0;
if (indf == -1)
indf = i;
if (i > 0 && s[i - 1] == '1' )
ans += 2;
else
ans += 1;
}
}
int curr;
while (k > 0 && !ls.empty()) {
curr = *ls.begin();
if (k >= curr) {
ans += (2 * curr + 1);
k -= curr;
}
else {
ans += (2 * k);
k = 0;
}
ls.erase(ls.begin());
}
if (k > 0) {
ans += (2 * min(k,
n - (ind + 1))
- 1);
k -= min(k, n - (ind + 1));
if (ind > -1)
ans++;
}
if (k > 0) {
ans += (min(indf, k) * 2 - 1);
if (indf > -1)
ans++;
}
return ans;
}
int main()
{
string str = "1110000101" ;
int N = str.length();
int K = 3;
cout << findMax(str, N, K);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int findMax(String s, int n, int k)
{
var ans = 0 ;
var l = 0 ;
var ind = - 1 ;
var indf = - 1 ;
var ls = new TreeSet<Integer>();
for (var i = 0 ; i < n; i++) {
if (s.charAt(i) == '0' )
l += 1 ;
else if ((s.charAt(i) == '1' ) && (l > 0 )
&& (ans != 0 )) {
ls.add(l);
l = 0 ;
}
if (s.charAt(i) == '1' ) {
ind = i;
l = 0 ;
if (indf == - 1 )
indf = i;
if ((i > 0 ) && (s.charAt(i - 1 ) == '1' ))
ans += 2 ;
else
ans += 1 ;
}
}
var curr = 0 ;
while (k > 0 && (ls.size() != 0 )) {
for (var i : ls)
{
curr = i;
break ;
}
if (k >= curr) {
ans += ( 2 * curr + 1 );
k -= curr;
}
else {
ans += ( 2 * k);
k = 0 ;
}
ls.remove(curr);
}
if (k > 0 ) {
ans += ( 2 * Math.min(k, n - (ind + 1 )) - 1 );
k -= Math.min(k, n - (ind + 1 ));
if (ind > - 1 )
ans += 1 ;
}
if (k > 0 ) {
ans += (Math.min(indf, k) * 2 - 1 );
if (indf > - 1 )
ans += 1 ;
}
return ans;
}
public static void main(String[] args)
{
var s = "1110000101" ;
var N = s.length();
var K = 3 ;
System.out.println(findMax(s, N, K));
}
}
|
Python3
def findMax( s, n, k):
ans = 0 ;
l = 0 ;
ind = - 1 ;
indf = - 1 ;
ls = set ([])
for i in range (n):
if (s[i] = = '0' ):
l + = 1
elif (s[i] = = '1'
and l > 0 and ans ! = 0 ):
ls.add(l);
l = 0 ;
if (s[i] = = '1' ) :
ind = i;
l = 0 ;
if (indf = = - 1 ):
indf = i;
if (i > 0 and s[i - 1 ] = = '1' ):
ans + = 2 ;
else :
ans + = 1 ;
curr = 0
while (k > 0 and len (ls)! = 0 ):
for i in ls:
curr = i
break
if (k > = curr):
ans + = ( 2 * curr + 1 );
k - = curr;
else :
ans + = ( 2 * k);
k = 0 ;
ls.remove(curr);
if (k > 0 ) :
ans + = ( 2 * min (k,
n - (ind + 1 ))
- 1 );
k - = min (k, n - (ind + 1 ));
if (ind > - 1 ):
ans + = 1
if (k > 0 ):
ans + = ( min (indf, k) * 2 - 1 );
if (indf > - 1 ):
ans + = 1
return ans
if __name__ = = "__main__" :
s = "1110000101" ;
N = len (s)
K = 3 ;
print (findMax(s, N, K));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int findMax( string s, int n, int k)
{
var ans = 0;
var l = 0;
var ind = -1;
var indf = -1;
var ls = new SortedSet< int >();
for ( var i = 0; i < n; i++) {
if (s[i] == '0' )
l += 1;
else if ((s[i] == '1' ) && (l > 0)
&& (ans != 0)) {
ls.Add(l);
l = 0;
}
if (s[i] == '1' ) {
ind = i;
l = 0;
if (indf == -1)
indf = i;
if ((i > 0) && (s[i - 1] == '1' ))
ans += 2;
else
ans += 1;
}
}
var curr = 0;
while (k > 0 && (ls.Count != 0)) {
foreach ( var i in ls)
{
curr = i;
break ;
}
if (k >= curr) {
ans += (2 * curr + 1);
k -= curr;
}
else {
ans += (2 * k);
k = 0;
}
ls.Remove(curr);
}
if (k > 0) {
ans += (2 * Math.Min(k, n - (ind + 1)) - 1);
k -= Math.Min(k, n - (ind + 1));
if (ind > -1)
ans += 1;
}
if (k > 0) {
ans += (Math.Min(indf, k) * 2 - 1);
if (indf > -1)
ans += 1;
}
return ans;
}
public static void Main( string [] args)
{
var s = "1110000101" ;
var N = s.Length;
var K = 3;
Console.WriteLine(findMax(s, N, K));
}
}
|
Javascript
function findMax( s, n, k)
{
let ans = 0;
let l = 0;
let ind = -1;
let indf = -1;
let ls = new Set()
for ( var i = 0; i < n; i++)
{
if (s[i] == '0' )
l+=1
else if ( (s[i] == '1' ) && (l > 0) && (ans != 0))
{
ls.add(l);
l = 0;
}
if (s[i] == '1' )
{
ind = i;
l = 0;
if (indf == -1)
indf = i;
if ((i > 0) && (s[i - 1] == '1' ))
ans += 2;
else
ans += 1;
}
}
let curr = 0
while (k > 0 && (ls.length!=0))
{
ls1 = Array.from(ls)
ls1.sort()
for (let i of ls1)
{
curr = i
break
}
if (k >= curr)
{
ans += (2 * curr + 1);
k -= curr;
}
else
{
ans += (2 * k);
k = 0;
}
ls. delete (curr);
}
if (k > 0)
{
ans += (2 * Math.min(k, n - (ind + 1)) - 1);
k -= Math.min(k, n - (ind + 1));
if (ind > -1)
ans+=1
}
if (k > 0)
{
ans += ( Math.min(indf, k) * 2 - 1);
if (indf > -1)
ans +=1
}
return ans
}
let s = "1110000101" ;
let N = s.length
let K = 3;
console.log(findMax(s, N, K));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
22 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...