Find an N-length Binary String having maximum sum of elements from given ranges


We will be given an array that will contain the pairs which represent the range and their value will range from 0(inclusive) to N(exclusive). Here, N is the size of the binary string which we have to return as the answer. For all the given ranges we have to maximize the sum of the product of the frequencies of zero and one. We will implement two approaches one is the naive approach by finding all the strings and another is the efficient solution.

Sample Examples

Input 1

Given array: {{1,3}, {2,4}, {2,5}}

Length of string: 6

Output − 101010 (there may be another output but each of them will be given the maximum result of 8).

Explanation − For the range 1 to 3 we have a frequency of 1 is 1 and zero is 2, for the range 2 to 4 frequency of 1 is 2 and zero is 1, and for the range 2 to 5 both 1 and zero have the frequency of 2. This gives us the sum of (1*2) + (2*1) + (2*2) which is 8 and the maximum possible.

Input 2

Given array: {{1,2}}

Length of string: 3

Output 101 (maximum output is 1 that can be given from 001, 010, 101, 110).

Explanation − All the possible strings are 000, 001, 010, 100, 011, 101, 110, 111. The maximum sum that can be achieved is 1.

Naive Approach

We have seen the examples, now let us move to the main approach.

In this approach, we will generate all the possible binary strings and after getting them will check for each of them which is producing the best possible sum. We will use the recursion to produce all the strings and then for each string we will calculate the sum of the product of frequencies and later compare with the maximum one.

Example

#include <iostream>
using namespace std;
int maxSum = 0;
string ansStr = "";
// function to generate all the strings 
void backtracking(string& str, int idx, int arr[][2], int m, int n){
   if(idx == n){
      int curSum = 0;
      for(int i=0;i<m;i++){
         int freqZ = 0, freqO = 0;
         for(int j=arr[i][0]; j <= arr[i][1]; j++){
            if(str[j] == '1'){
               freqO++;
            }
            else{
               freqZ++;
            }
         }
         curSum += freqO*freqZ;
      }
      if(maxSum < curSum){
         maxSum = curSum;
         ansStr = str;
      }
      return;
   }    
   // adding zero at the current index and calling function 
   str.push_back('0');
   backtracking(str,idx+1,arr,m,n);    
   // updating 0 to 1 and calling function 
   str[idx] = '1';
   backtracking(str,idx+1,arr,m,n);    
   str.pop_back(); // poping the last element
}
string findString(int arr[][2], int m, int n){
   // updating the value of maxSum and ansStr 
   ansStr = "";
   maxSum = 0;
   string temp = "";
   // calling to the function 
   backtracking(temp,0,arr,m,n);    
   return ansStr;
}
int main(){
   int arr[][2] = {{1,3}, {2,4}, {2,5}}; // given array 
   int m = 3; // size of array 
   int n = 6; // length of the string     
   // calling the function 
   string str = findString(arr,m,n);    
   cout<<"The string which will produce the maximum result is "<<str<<endl;
   return 0;
}

Output

The string which will produce the maximum result is 000101

Time and Space Complexity

The time complexity of the above code is very in-efficient which is O(2^N*M*N) where N is the size of the string and M is the size of the given array.

The space complexity of the above code is O(N), where N is the size of the string.

Efficient Approach

In the previous approach, we are creating every string and then we are testing for them which is taking the O(N) space complexity and O(2^N*N) time complexity which is not efficient at all. To make the process easy we can think by an observation.

To get the maximum product we can think of reducing the absolute difference between the frequency of ones and zeros. To do so putting the elements in the alternative position is the best way to do and this will make the time complexity linear. Let us see the code −

Example

#include <iostream>
using namespace std;
string findString(int n){
   // making the alternative ones and zeros string 
   string ans = "";    
   // adding total of n elements in the string 
   for(int i=0; i<n; i++){
      if(i & 1){
         // if the current index is odd add zero to the string 
         ans += '0';
      }
      else{
         // if the current index is even add one to the string 
         ans += '1';
      }
   }
   return ans;
}
int main(){
   int arr[][2] = {{1,3}, {2,4}, {2,5}}; // given array 
   int m = 3; // size of array 
   int n = 6; // length of the string     
   // calling the function 
   string str = findString(n);    
   cout<<"The string which will produce the maximum result is "<<str<<endl;
   return 0;
}

Output

The string which will produce the maximum result is 101010

Time and Space Complexity

The time complexity of the above code is O(N) where N is the length of the string, which is the linear time complexity.

The space complexity of the above approach is O(1), as we are not using any extra space here.

Conclusion

In this tutorial, we have implemented two approaches to create a string that will produce the maximum sum for the frequencies of the one and zero present in given range provided by an array. We have implemented first approach using the backtracking but it costs the time complexity of exponential. Later we have implemented a efficient approach with observation.

Updated on: 17-May-2023

108 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements