Construct a K-length binary string from an array based on given conditions


In this tutorial, we require to construct a binary string of length K such that it should contain ‘1’ at the ith index if a subset-sum equal to I is possible using array elements. We will learn two approaches to solving the problem. In the first approach, we will use a dynamic programming approach to check whether the subset sum equal to index ‘I’ is possible. In the second approach, we will use a bitset to find all possible sums using array elements.

Problem statement − We have given an array containing N integers. Also, we have given integer M representing the length of the binary string. We need to create a binary string of length M such that it follows the below condition.

  • If we can find the subset from the array with a sum equal to index ‘I’, the character at index ‘I’ is 1; Otherwise, 0.

  • The index I start from 1.

Sample Examples

Input –  arr = [1, 2] M = 4
Output – 1110

Explanation

  • The subset with a sum equal to 1 is {1}.

  • The subset with a sum equal to 2 is {2}.

  • The subset with a sum equal to 3 is {1, 2}.

  • We can’t find the subset with a sum equal to 4, so we placed 0 at the 4th index.

Input –  arr = [1, 3, 1] M = 9
Output – 111110000

Explanation

We can create all possible combinations to get a sum between 1 to 5. So, the first 5 characters are 1, and the last 4 characters are 0.

Input –  arr = [2, 6, 3] M = 6
Output – 011011

Explanation

The sum equal to 1 and 4 is not possible using array elements, so we placed 0 at the first and fourth index.

Approach 1

In this approach, we will use dynamic programming to check whether we can construct the sum equal to index ‘I’ using the array elements. We will check it for every index and append 1 or 0 to a binary string.

Algorithm

  • Step 1 − Create a vector of size N and initialize it with integer values. Also, define the ‘bin’ variable of the string type and initialize it with an empty string.

  • Step 2 − Use the for loop to make total M iterations equal to the string length.

  • Step 3 − In the for loop, invoke the isSubsetSum() function by passing an array, N, and index value as a parameter.

  • Step 4 − If the isSubsetSum() function returns true, append ‘1’ to ‘bin’. Otherwise, append ‘0’ to ‘bin’.

  • Step 5 − Define the isSubsetSum() function to check whether the sum is possible using array elements.

  • Step 5.1 − Define a 2D vector called dpTable.

  • Step 5.2 − Initialize ‘dpTable[i][0]’ with true as sum zero is always possible. Here, ‘I’ is the index value.

  • Step 5.3 − Initialize ‘dpTable[0][j]’ with false as the sum is not possible for an empty array.

  • Step 5.4 − Now, use two nested loops. The first loop is making iterations from 1 to N, and another is making iterations from 1 to sum.

  • Step 5.5 − In the for loop, if the current element’s value is greater than the sum, ignore it.

  • Step 5.6 − Otherwise, include or exclude elements to get the sum.

  • Step 5.7 − Return the ‘dpTable[N][sum]’ containing the result.

Example

#include <iostream>
#include <vector>
using namespace std;
// Function to check if subset-sum is possible
bool isSubsetSum(vector<int> &arr, int N, int sum){
   vector<vector<bool>> dpTable(N + 1, vector<bool>(sum + 1, false));
   
   // Base cases
   for (int i = 0; i <= N; i++)
   
      // If the sum is zero, then the answer is true
      dpTable[i][0] = true;
      
   // for an empty array, the sum is not possible
   for (int j = 1; j <= sum; j++)
      dpTable[0][j] = false;
      
   // Fill the dp table
   for (int i = 1; i <= N; i++){
      for (int j = 1; j <= sum; j++){
      
         // if the current element is greater than the sum, then we can't include it
         if (arr[i - 1] > j)
            dpTable[i][j] = dpTable[i - 1][j];
            
         // else we can either include it or exclude it to get the sum
         else
            dpTable[i][j] = dpTable[i - 1][j] || dpTable[i - 1][j - arr[i - 1]];
      }
   }
   
   // The last cell of the dp table contains the result
   return dpTable[N][sum];
}
int main(){

   // Given M
   int M = 9;
   
   // Creating the vector
   vector<int> arr = {1, 3, 1};
   
   // getting the size of the vector
   int N = arr.size();
   
   // Initializing the string
   string bin = "";
   
   // Making k iteration to construct the string of length k
   for (int i = 1; i <= M; i++){
   
      // if the subset sum is possible, then add 1 to the string, else add 0
      if (isSubsetSum(arr, N, i)){
         bin += "1";
      }
      else{
         bin += "0";
      }
   }
   
   // print the result.
   cout << "The constructed binary string of length " << M << " according to the given conditions is ";
   cout << bin;
   return 0;
}

Output

The constructed binary string of length 9 according to the given conditions is 111110000

Time complexity − O(N^3), as isSubsetSum() has O(N^2) time complexity, and we call it N times from the driver code.

Space complexity − O(N^2), as we use a 2D vector in the isSubsetSum() function.

Approach 2: Using the Bitset

In this approach, we will use a bitset to find all possible sum values by combining different elements of the array. Here, bitset means it creates a binary string. In the resultant bitset, every bit of it represents whether a sum equal to a particular index is possible, which we need to find here.

Algorithm

  • Step 1 − Define the array and M. Also, define the createBinaryString() function.

  • Step 2 − Next, define the bitset of require length, which creates a binary string.

  • Step 3 − Initialize bit[0] with 1, as sum 0 is always possible.

  • Step 4 − Use for loop to iterate through array elements

  • .
  • Step 5 − First, perform the left shift operation of ‘bit’ with the array element. After that, perform the ‘or’ operation of the resultant value and ‘bit’ value.

  • Step 6 − Print the bitset values starting from index 1 to M.

Example

#include <bits/stdc++.h>
using namespace std;
// function to construct the binary string
void createBinaryString(int array[], int N, int M){
   bitset<100003> bit;
   
   // Initialize with 1
   bit[0] = 1;
   
   // iterate over all the integers
   for (int i = 0; i < N; i++){
      // perform left shift by array[i], and OR with the previous value.
      bit = bit | bit << array[i];
   }
   
   // Print the binary string
   cout << "The constructed binary string of length " << M << " according to the given conditions is ";
   for (int i = 1; i <= M; i++){
      cout << bit[i];
   }
}
int main(){

   // array of integers
   int array[] = {1, 4, 2};
   int N = sizeof(array) / sizeof(array[0]);
   
   // value of M, size of the string
   int M = 8;
   createBinaryString(array, N, M);
}

Output

The constructed binary string of length 8 according to the given conditions is 11111110

Time complexity − O(N), as we use single for loop.

Space complexity − O(N), as we store bitset value.

Conclusion

Here, we optimized the second approach, which is better than the first approach in terms of space and time complexity. However, the second approach can be hard for beginners to understand if you don’t have a knowledge of the bitset.

Updated on: 28-Jul-2023

72 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements