Given an array arr[] consisting of N integers, the task is to find the total number of distinct subsequences having Binary Equivalence.
A subsequence has Binary Equivalence if the sum of the count of set and unset bits in the binary representations of all the decimal numbers across the subsequence are equal.
Examples:
Input: arr[] = {2, 7, 10}
Output: 0011
Explanation:
2 ? 0010?1’s = 1, 0’s = 3
7 ? 0111?1’s = 3, 0’s = 1
10 ? 1010?1’s = 2, 0’s = 2
The subsequence [2, 7, 10] has Binary Equivalence because the number of 0’s and 1’s across the subsequence is 6 each.
Similarly, [2, 7] also has Binary Equivalence of 4 each.Â
But [7, 10] does not have Binary Equivalence.Â
Likewise, [10] has Binary Equivalence of 2 each.Â
The total number of unique subsequences where Binary Equivalence is possible is 3.Â
Since 10 is the largest element in the given array and the number of bits required to represent 10 in binary is 4. Hence, the number of bits present in the output needs to be 4.Input: arr[] = {5, 7, 9, 12}
Output: 0111
Approach: The idea is to find the total number of bits required to represent the maximum element of the array.Follow these steps to solve this problem:
- Find the maximum element and the length of binary representation of the maximum element.
- Append 0 in the front other elements in binary representation, to make the number of bits in each element equal to the maximum number bits.
- Find all the subsequences of the given array.
- Find the total number of subsequences that have Binary Equivalence.
- Convert the total number into binary and append 0s if the length of the total number is less than the length of the maximum number to make both the lengths equal.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h> using namespace std; Â
// C++ program for the above approach Â
// Function to find the number of // subsequences having Binary Equivalence void numberOfSubsequence(vector< int > arr) { Â
  // Find the maximum array element   int maxElement = INT_MIN;   for ( auto x: arr) maxElement = max(x, maxElement); Â
  // Convert the maximum element   // to its binary equivalent   int val = ( int )(log2(maxElement));   string maxBinary = bitset<64>(maxElement).to_string().substr(64 - val - 1); Â
  // Dictionary to store the count of   // set and unset bits of all array elements   map< int ,pair< int , int >> dic; Â
Â
  for ( auto i: arr){     int temp = ( int )(log2(maxElement));     string str = bitset<64>(i).to_string().substr(64 - temp - 1); Â
    if (str.size() <= maxBinary.size()) {       int diff = maxBinary.size() - str.size(); Â
      // Add the extra zeros before all       // the elements which have length       // smaller than the maximum element       for ( int indx = 0; indx < diff; indx++){         str = '0' + str;       }     } Â
    int zeros = 0;     int ones = 0;     for ( int i = 0; i < str.size(); i++){       if (str[i] == '0' ) zeros++;       else ones++;     } Â
Â
    // Fill the dictionary with number     // of 0's and 1's     dic[i] = {zeros, ones};   } Â
  vector<vector< int >> allCombinations;   vector< int > curr_temp;   allCombinations.push_back(curr_temp); Â
  // Find all the combinations   for ( int i : arr) {     // cout << "hi" << endl;     vector<vector< int >> newCombinations;     for ( auto j : allCombinations) {       vector< int > combination = j;       combination.push_back(i);       newCombinations.push_back(combination); Â
    }     for ( auto curr_list: newCombinations){       allCombinations.push_back(curr_list);     }   } Â
  int count = 0;   // Find all the combinations where   // sum_of_zeros == sum_of_ones   for ( int i = 1; i < allCombinations.size(); i++) {     int sum0 = 0;     int sum1 = 0;     for ( auto j: allCombinations[i]) {       sum0 += dic[j].first;       sum1 += dic[j].second;     } Â
    // Count the total combinations     // where sum_of_zeros = sum_of_ones     if (sum0 == sum1) {       count += 1;     }   } Â
  // Convert the count number to its   // binary equivalent   int curr_val = ( int )(log2(count));   string str = bitset<64>(count).to_string().substr(64 - curr_val - 1);   if (str.size() <= maxBinary.size()) {     int diff = maxBinary.size() - str.size(); Â
    // Append leading zeroes to     // the answer if its length is     // smaller than the maximum element     for ( int i = 0; i < diff; i++){       str = '0' + str;     }   } Â
  // Print the result   cout << str << endl; } Â
// Driver Code int main(){ Â
  // Given arr[] arr.   vector< int > arr = {5, 7, 9, 12}; Â
  // Function Call   numberOfSubsequence(arr); Â
  return 0; } Â
// The code is contributed by Nidhi goel. |
Java
import java.util.*; Â
class Main { Â Â public static void main(String[] args) { Â Â Â Â int [] arr = { 5 , 7 , 9 , 12 }; Â Â Â Â numberOfSubsequence(arr); Â Â } Â
  // Function to find the number of subsequences   // having Binary Equivalence   static void numberOfSubsequence( int [] arr) { Â
    // Find the maximum array element     int maxElement = Arrays.stream(arr).max().getAsInt(); Â
    // Convert the maximum element to its binary equivalent     String maxBinary = Integer.toBinaryString(maxElement); Â
    // Dictionary to store the count of set and unset bits     // of all array elements     Map<Integer, int []> dic = new HashMap<>();     for ( int i : arr) {       String str = Integer.toBinaryString(i);       if (str.length() < maxBinary.length()) {         int diff = maxBinary.length() - str.length();         // Add extra zeros before all the elements which have length         // smaller than the maximum element         str = "0" .repeat(diff) + str;       } Â
      // Fill the dictionary with number of 0's and 1's       int zeros = str.length() - str.replaceAll( "0" , "" ).length();       int ones = str.length() - str.replaceAll( "1" , "" ).length();       dic.put(i, new int []{zeros, ones});     } Â
    List<List<Integer>> allCombinations = new ArrayList<>();     allCombinations.add( new ArrayList<>()); Â
    // Find all the combinations     for ( int i : arr) {       List<List<Integer>> newCombinations = new ArrayList<>();       for (List<Integer> j : allCombinations) {         List<Integer> combination = new ArrayList<>(j);         combination.add(i);         newCombinations.add(combination);       }       allCombinations.addAll(newCombinations);     } Â
    int count = 0 ;     // Find all the combinations where sum_of_zeros == sum_of_ones     for ( int i = 1 ; i < allCombinations.size(); i++) {       int sum0 = 0 ;       int sum1 = 0 ;       for ( int j : allCombinations.get(i)) {         sum0 += dic.get(j)[ 0 ];         sum1 += dic.get(j)[ 1 ];       } Â
      // Count the total combinations where sum_of_zeros = sum_of_ones       if (sum0 == sum1) {         count += 1 ;       }     } Â
    // Convert the count number to its binary equivalent     String str = Integer.toBinaryString(count);     if (str.length() < maxBinary.length()) {       int diff = maxBinary.length() - str.length();       // Append leading zeroes to the answer if its length is       // smaller than the maximum element       str = "0" .repeat(diff) + str;     } Â
    // Print the result     System.out.println(str);   } } |
Python3
# Python program for the above approach import itertools Â
# Function to find the number of # subsequences having Binary Equivalence def numberOfSubsequence(arr): Â
    # Find the maximum array element     Max_element = max (arr) Â
    # Convert the maximum element     # to its binary equivalent     Max_Binary = "{0:b}" . format ( int (         Max_element)) Â
    # Dictionary to store the count of     # set and unset bits of all array elements     Dic = {} Â
    for i in arr:         Str = "{0:b}" . format ( int (i)) Â
        if len ( Str ) < = len (Max_Binary):             diff = len (Max_Binary) - len ( Str ) Â
            # Add the extra zeros before all             # the elements which have length             # smaller than the maximum element             Str = ( '0' * diff) + Str Â
        zeros = Str .count( '0' )         ones = Str .count( '1' ) Â
        # Fill the dictionary with number         # of 0's and 1's         Dic[ int (i)] = [zeros, ones] Â
    all_combinations = [] Â
    # Find all the combination     for r in range ( len (arr) + 1 ): Â
        comb = itertools.combinations(arr, r)         comlist = list (comb)         all_combinations + = comlist     count = 0 Â
    # Find all the combinations where     # sum_of_zeros == sum_of_ones     for i in all_combinations[ 1 :]:         sum0 = 0         sum1 = 0         for j in i:             sum0 + = Dic[j][ 0 ]             sum1 + = Dic[j][ 1 ] Â
        # Count the total combinations         # where sum_of_zeros = sum_of_ones         if sum0 = = sum1:             count + = 1 Â
    # Convert the count number to its     # binary equivalent     Str = "{0:b}" . format ( int (count))     if len ( Str ) < = len (Max_Binary):         diff = len (Max_Binary) - len ( Str ) Â
        # Append leading zeroes to         # the answer if its length is         # smaller than the maximum element         Str = ( '0' * diff) + Str Â
    # Print the result     print ( Str ) Â
Â
# Driver Code Â
# Give array arr[] arr = [ 5 , 7 , 9 , 12 ] Â
# Function Call numberOfSubsequence(arr) |
C#
// Following is the C# equivalent of the above Java code using System; using System.Collections.Generic; using System.Linq; Â
namespace NumberOfSubsequence {     class Program     {         static void Main( string [] args)         {             int [] arr = { 5, 7, 9, 12 };             NumberOfSubsequence(arr);         } Â
        // Function to find the number of subsequences         // having Binary Equivalence         static void NumberOfSubsequence( int [] arr)         {             // Find the maximum array element             int maxElement = arr.Max(); Â
            // Convert the maximum element to its binary equivalent             string maxBinary = Convert.ToString(maxElement, 2); Â
            // Dictionary to store the count of set and unset bits             // of all array elements             Dictionary< int , int []> dic = new Dictionary< int , int []>();             foreach ( int i in arr)             {                 string strr = Convert.ToString(i, 2);                 if (strr.Length < maxBinary.Length)                 {                     int diff = maxBinary.Length - strr.Length;                     // Add extra zeros before all the elements which have length                     // smaller than the maximum element                     strr = new string ( '0' , diff) + strr;                 } Â
                // Fill the dictionary with number of 0's and 1's                 int zeros = strr.Length - strr.Replace( "0" , "" ).Length;                 int ones = strr.Length - strr.Replace( "1" , "" ).Length;                 dic.Add(i, new int [] { zeros, ones });             } Â
            List<List< int >> allCombinations = new List<List< int >>();             allCombinations.Add( new List< int >()); Â
            // Find all the combinations             foreach ( int i in arr)             {                 List<List< int >> newCombinations = new List<List< int >>();                 foreach (List< int > j in allCombinations)                 {                     List< int > combination = new List< int >(j);                     combination.Add(i);                     newCombinations.Add(combination);                 }                 allCombinations.AddRange(newCombinations);             } Â
            int count = 0;             // Find all the combinations where sum_of_zeros == sum_of_ones             for ( int i = 1; i < allCombinations.Count; i++)             {                 int sum0 = 0;                 int sum1 = 0;                 foreach ( int j in allCombinations[i])                 {                     sum0 += dic[j][0];                     sum1 += dic[j][1];                 } Â
                // Count the total combinations where sum_of_zeros = sum_of_ones                 if (sum0 == sum1)                 {                     count += 1;                 }             } Â
            // Convert the count number to its binary equivalent             string str = Convert.ToString(count, 2);             if (str.Length < maxBinary.Length)             {                 int diff = maxBinary.Length - str.Length;                 // Append leading zeroes to the answer if its length is                 // smaller than the maximum element                 str = new string ( '0' , diff) + str;             } Â
            // Print the result             Console.WriteLine(str);         }     } } |
Javascript
// JavaScript program for the above approach Â
// Function to find the number of // subsequences having Binary Equivalence function numberOfSubsequence(arr) { Â
  // Find the maximum array element   let maxElement = Math.max(...arr); Â
  // Convert the maximum element   // to its binary equivalent   let maxBinary = maxElement.toString(2); Â
  // Dictionary to store the count of   // set and unset bits of all array elements   let dic = {}; Â
  for (let i of arr) {     let str = i.toString(2); Â
    if (str.length <= maxBinary.length) {       let diff = maxBinary.length - str.length; Â
      // Add the extra zeros before all       // the elements which have length       // smaller than the maximum element       str = '0' .repeat(diff) + str;     } Â
    let zeros = str.split( '0' ).length - 1;     let ones = str.split( '1' ).length - 1; Â
    // Fill the dictionary with number     // of 0's and 1's     dic[i] = [zeros, ones];   } Â
  let allCombinations = [[]]; Â
  // Find all the combination   for (let i of arr) {     let newCombinations = [];     for (let j of allCombinations) {       newCombinations.push(j.concat(i));     }     allCombinations = allCombinations.concat(newCombinations);   }   let count = 0; Â
  // Find all the combinations where   // sum_of_zeros == sum_of_ones   for (let i = 1; i < allCombinations.length; i++) {     let sum0 = 0;     let sum1 = 0;     for (let j of allCombinations[i]) {       sum0 += dic[j][0];       sum1 += dic[j][1];     } Â
    // Count the total combinations     // where sum_of_zeros = sum_of_ones     if (sum0 == sum1) {       count += 1;     }   } Â
  // Convert the count number to its   // binary equivalent   let str = count.toString(2);   if (str.length <= maxBinary.length) {     let diff = maxBinary.length - str.length; Â
    // Append leading zeroes to     // the answer if its length is     // smaller than the maximum element     str = '0' .repeat(diff) + str;   } Â
  // Print the result   console.log(str); } Â
// Driver Code Â
// Give array arr[] let arr = [5, 7, 9, 12]; Â
// Function Call numberOfSubsequence(arr); |
0111
Â
Time Complexity: O(2N)
Auxiliary Space: O(N2)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!