Open In App

Count of subsequences from a given Array having Binary Equivalence

Last Updated : 14 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. Find the maximum element and the length of binary representation of the maximum element.
  2. 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.
  3. Find all the subsequences of the given array.
  4. Find the total number of subsequences that have Binary Equivalence.
  5. 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);


Output: 

0111

 

Time Complexity: O(2N)
Auxiliary Space: O(N2)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads