Skip to content
Related Articles

Related Articles

Improve Article

Arrange a binary string to get maximum value within a range of indices

  • Difficulty Level : Hard
  • Last Updated : 26 May, 2021

Given a string consisting of only 0’s and 1’s. Now you are given N non-intersecting ranges L, R ( L <= R), more specifically [L1, R1], [L2, R2], …, [LN, RN], No two of these intervals overlap — formally, for each valid i, j such that i!=j, either Ri<Lj or Rj<Li. 
The task is to find a valid permutation that will hold two following conditions simultaneously:  

  1. The sum of numbers between all N-given ranges will be the maximum.
  2. The string will be lexicographically largest. A string 1100 is lexicographically larger than string 1001.

Examples:  

Input 
11100 

2 3 
5 5 
Output 
01101
First we put 1’s in position 2 and 3 then in 5 as 
there are no 1’s left, the string formed is 01101.
Input 
0000111 

1 1 
1 2 
Output 
1110000
In the above example, we, 1st put 1 in 1st and 2nd position, then we have another ‘1’ left, 
So, we use it to maximize the string lexicographically and we put it in the 3rd position and thus the rearrangement is complete.  

Approach  

  • First priority is given to making the count of 1’s between all l and r be max. We count the number of 1’s in the array and store them in a variable.
  • After taking input, we update the range of each l and r by 1 to just mark the position to be filled with 1 first.
  • Then, we take the prefix sum of the array so that we get the position where to fix the 1’s first. Then we run a loop in that prefix sum array from the left. If we get any position with a value greater than 1, that means we have a l-r in that index. We continue to put 1’s in those indices until the count of 1 becomes zero.
  • Now, after the maximization operation is finished and if there are some 1’s left, then we start the lexicographic maximization. We again start a loop from the left of the prefix sum array. If we find an index having the value 0 which indicates that there is no l-r having that index, then we put a 1 in that index and thus continue until all remaining 1’s are filled.

Below is the implementation of the above approach: 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
void arrange(string s)
{
    int cc = 0;
 
    // Storing the count of 1's in the string
    for (int i = 0; i < s.length(); i++)
    {
        if (s[i] == '1') cc++;
    }
 
    int a[s.length() + 1] = {0};
 
    // Query of l and r
    int qq[][2] = {{2, 3}, {5, 5}};
 
    int n = sizeof(qq) / sizeof(qq[0]);
    for (int i = 0; i < n; i++)
    {
        int l = qq[i][0], r = qq[i][1];
        l--, r--;
        a[l]++;
 
        // Applying range update technique.
        a[r + 1]--;
    }
 
    int len_a = sizeof(a) / sizeof(a[0]);
    for (int i = 1; i < len_a; i++)
    {
        // Taking prefix sum to get the range update values
        a[i] += a[i - 1];
    }
 
    // Final array which will store the arranged string
    int zz[s.length()] = {0};
 
    for (int i = 0; i < len_a - 1; i++)
    {
        if (a[i] > 0)
        {
            if (cc > 0)
            {
                zz[i] = 1;
                cc--;
            }
            else
                break;
        }
 
        if (cc == 0) break;
    }
 
    // if after maximizing the ranges any 1 is left
    // then we maximize the string lexicographically.
    if (cc > 0)
    {
        for (int i = 0; i < s.length(); i++)
        {
            if (zz[i] == 0)
            {
                zz[i] = 1;
                cc--;
            }
            if (cc == 0) break;
        }
    }
 
    for (int i = 0; i < s.length(); i++)
        cout << zz[i];
    cout << endl;
}
 
// Driver Code
int main()
{
    string str = "11100";
    arrange(str);
    return 0;
}
 
// This code is contributed by
// sanjeev2552

Java




// Java implementation of the approach
class GFG
{
 
static void arrange(String s)
{
    int cc = 0;
 
    // Storing the count of 1's in the String
    for (int i = 0; i < s.length(); i++)
    {
        if (s.charAt(i) == '1') cc++;
    }
 
    int []a = new int[s.length() + 1];
 
    // Query of l and r
    int qq[][] = {{2, 3}, {5, 5}};
 
    int n = qq.length;
    for (int i = 0; i < n; i++)
    {
        int l = qq[i][0], r = qq[i][1];
        l--; r--;
        a[l]++;
 
        // Applying range update technique.
        a[r + 1]--;
    }
 
    int len_a = a.length;
    for (int i = 1; i < len_a; i++)
    {
        // Taking prefix sum to get the range update values
        a[i] += a[i - 1];
    }
 
    // Final array which will store the arranged String
    int []zz = new int[s.length()];
 
    for (int i = 0; i < len_a - 1; i++)
    {
        if (a[i] > 0)
        {
            if (cc > 0)
            {
                zz[i] = 1;
                cc--;
            }
            else
                break;
        }
 
        if (cc == 0) break;
    }
 
    // if after maximizing the ranges any 1 is left
    // then we maximize the String lexicographically.
    if (cc > 0)
    {
        for (int i = 0; i < s.length(); i++)
        {
            if (zz[i] == 0)
            {
                zz[i] = 1;
                cc--;
            }
            if (cc == 0) break;
        }
    }
    for (int i = 0; i < s.length(); i++)
        System.out.print(zz[i]);
    System.out.println();
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "11100";
    arrange(str);
}
}
 
// This code is contributed by Rajput-Ji

Python3




# Python implementation of the approach
def arrange(s):
    cc = 0
 
    # Storing the count of 1's in the string
    for i in range(len(s)):
        if(s[i]=="1"):
            cc+= 1
    a =[0]*(len(s)+1)
 
    # Query of l and r
    qq =[(2, 3), (5, 5)]
 
    n = len(qq)
    for i in range(n):
        l, r = qq[i][0], qq[i][1]
        l-= 1
        r-= 1
        a[l]+= 1
 
        # Applying range update technique.
        a[r + 1]-= 1
 
    for i in range(1, len(a)):
 
        # Taking prefix sum to get the range update values
        a[i]= a[i]+a[i-1]
 
    # Final array which will store the arranged string
    zz =[0]*len(s)
 
    for i in range(len(a)-1):
        if(a[i]>0):
            if(cc>0):
                zz[i]= 1
                cc-= 1
            else:
                break
        if(cc == 0):
            break
 
    # if after maximizing the ranges any 1 is left
    # then we maximize the string lexicographically.
    if(cc>0):
 
        for i in range(len(s)):
            if(zz[i]== 0):
                zz[i]= 1
                cc-= 1
            if(cc == 0):
                break
    print(*zz, sep ="")
 
str = "11100"
arrange(str)

C#




// C# implementation of the approach
using System;
 
class GFG
{
 
static void arrange(String s)
{
    int cc = 0;
 
    // Storing the count of 1's in the String
    for (int i = 0; i < s.Length; i++)
    {
        if (s[i] == '1') cc++;
    }
 
    int []a = new int[s.Length + 1];
 
    // Query of l and r
    int [,]qq = {{2, 3}, {5, 5}};
 
    int n = qq.GetLength(0);
    for (int i = 0; i < n; i++)
    {
        int l = qq[i, 0], r = qq[i, 1];
        l--; r--;
        a[l]++;
 
        // Applying range update technique.
        a[r + 1]--;
    }
 
    int len_a = a.Length;
    for (int i = 1; i < len_a; i++)
    {
        // Taking prefix sum to get the range update values
        a[i] += a[i - 1];
    }
 
    // Final array which will store the arranged String
    int []zz = new int[s.Length];
 
    for (int i = 0; i < len_a - 1; i++)
    {
        if (a[i] > 0)
        {
            if (cc > 0)
            {
                zz[i] = 1;
                cc--;
            }
            else
                break;
        }
 
        if (cc == 0) break;
    }
 
    // if after maximizing the ranges any 1 is left
    // then we maximize the String lexicographically.
    if (cc > 0)
    {
        for (int i = 0; i < s.Length; i++)
        {
            if (zz[i] == 0)
            {
                zz[i] = 1;
                cc--;
            }
            if (cc == 0) break;
        }
    }
    for (int i = 0; i < s.Length; i++)
        Console.Write(zz[i]);
    Console.WriteLine();
}
 
// Driver Code
public static void Main(String[] args)
{
    String str = "11100";
    arrange(str);
}
}
 
// This code is contributed by PrinciRaj1992

Javascript




<script>
 
// Javascript implementation of the approach
 
function arrange(s)
{
    var cc = 0;
 
    // Storing the count of 1's in the string
    for(var i = 0; i < s.length; i++)
    {
        if (s[i] == '1') cc++;
    }
 
    var a = Array(s.length+1).fill(0);
 
    // Query of l and r
    var qq = [[2, 3], [5, 5]];
 
    var n = qq.length;
    for (var i = 0; i < n; i++)
    {
        var l = qq[i][0], r = qq[i][1];
        l--, r--;
        a[l]++;
 
        // Applying range update technique.
        a[r + 1]--;
    }
 
    var len_a = a.length;
    for (var i = 1; i < len_a; i++)
    {
        // Taking prefix sum to get the range update values
        a[i] += a[i - 1];
    }
 
    // Final array which will store the arranged string
    var zz = Array(s.length).fill(0);
 
    for (var i = 0; i < len_a - 1; i++)
    {
        if (a[i] > 0)
        {
            if (cc > 0)
            {
                zz[i] = 1;
                cc--;
            }
            else
                break;
        }
 
        if (cc == 0) break;
    }
 
    // if after maximizing the ranges any 1 is left
    // then we maximize the string lexicographically.
    if (cc > 0)
    {
        for (var i = 0; i < s.length; i++)
        {
            if (zz[i] == 0)
            {
                zz[i] = 1;
                cc--;
            }
            if (cc == 0) break;
        }
    }
 
    for (var i = 0; i < s.length; i++)
        document.write( zz[i]);
    document.write("<br>");
}
 
// Driver Code
var str = "11100";
arrange(str);
 
 
</script>
Output: 
01101

 




My Personal Notes arrow_drop_up
Recommended Articles
Page :