Distinct Numbers Obtained By Generating All Permutations Of a Binary String


Problem Statement

We have given binary string str of length N. We need to find all permutations of the string, convert them to the decimal value, and return all unique decimal values.

Sample Examples

Input

str = ‘1’

Output

[1]

Explanation

All permutations of the ‘1’ is only ‘1’. So, the decimal value related to ‘1’ equals 1.

Input

str = ‘10’

Output

[1, 2]

Explanation

The permutations of ‘10’ are only ‘01’ and ‘10’, equivalent to 1 and 2, respectively.

Input

‘101’

Output

[3, 5, 6]

Explanation

All possible permutations of ‘101’ are ‘110’, ‘101’, ‘110’, ‘011’, ‘101’, and ‘011’, and if we convert them to decimal numbers, we get 3, 5, and 6 unique decimal numbers.

Approach 1

In the first approach, we will use backtracking to get all the permutations of the binary string. After that, we will convert binary permutations to decimal values and pick the unique decimal values using the set. We will use the pow() method and for loop to convert decimal to binary.

Algorithm

  • Step 1 − Define the ‘getDecimalPermutations()’ function to get the resultant decimal values.

  • Step 2 − Execute the ‘getBinaryPermutations()’ function to get all binary permutations of the string. Also, pass the string, left and right index, and permutation vector as a parameter.

  • Step 2.1 − In the ‘getBinaryPermutations()’ function, push the resultant string in the permutations list if the left and right indexes are equal.

  • Step 2.2 − If the left and right indexes are not equal, use for loop to iterate through the string from the left index to the right index.

  • Step 2.3 − Swap the characters at the ith and left indexes in the for loop.

  • Step 2.4 − Again, call the ‘getBinaryPermutations’ function with the same parameters as the argument and the ‘left + 1’ index.

  • Step 2.5 − Swap the characters at the ith index and left index for the backtracking purpose.

  • Step 3 − Create a set named ‘allDecimals’. After that, iterate through all permutations of the binary string.

  • Step 4 − Call the bToD() function to convert binary to decimal.

  • Step 4.1 − In the bToD() function, initialize a decimal variable with 0 value.

  • Step 4.2 − Use the for loop to make iterations in the binary string from the end, and add ‘(num[i] - '0') * pow(2, j)’ to the decimal value.

  • Step 4.3 − Return the decimal value.

  • Step 5 − In the ‘getDecimalPermutations’ function, insert the decimal value returned from bToD() function.

  • Step 6 − Print all values of the set, which will contain unique decimal values.

Example

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
// Function to convert binary to decimal
int bToD(string num){
   int decimal = 0;
   for (int i = num.size() - 1, j = 0; i >= 0; i--, j++){
      decimal += (num[i] - '0') * pow(2, j);
   }
   return decimal;
}
// Function to get all permutations of a binary string
void getBinaryPermutations(string str, int left, int right, vector<string> &permutations){
   // Base case
   if (left == right){
      // push_back() function is used to push elements into a vector from the back
      permutations.push_back(str);
   } else {
      // Permutations made
      for (int i = left; i <= right; i++){
         // Swapping done
         swap(str[left], str[i]);
         // Recursion called for next index (left + 1)
         getBinaryPermutations(str, left + 1, right, permutations);
         // Backtrack
         swap(str[left], str[i]);
      }
   }
}
void getDecimalPermutations(string str){
   vector<string> permutations;
   getBinaryPermutations(str, 0, str.length() - 1, permutations);
   set<int> allDecimals;
   for (const auto &p : permutations){
      allDecimals.insert(bToD(p));
   }
   cout << "All decimal numbers which we can achieve using permutations are " << endl;
   for (const auto &d : allDecimals){
      cout << d << " ";
   }
}
int main(){
   string bString = "101";
   getDecimalPermutations(bString);
   return 0;
}

Output

All decimal numbers which we can achieve using permutations are 
3 5 6
  • Time complexity − O(n!). The time complexity of ‘getBinaryPermutations()’ function is ‘n!’, as we use the backtracking to find all permutations. The time complexity of the bToD() function is O(n).

  • Space complexity − O(n!). Every string has n! permutations that we are storing in the list.

Approach 2

In this approach, we will use the next_permutation() function of C++ to generate the binary string permutations rather than the backtracking approach. Also, we changed the approach to convert the binary to decimal.

Algorithm

  • Step 1 − Define the ‘allNumbers’ set.

  • Step 2 − The sort() method is used to sort the binary string.

  • Step 3 − Use the do-while loop to iterate through every permutation of the string.

  • Step 4 − In the do-while loop, call the bToD() function by passing a string as a parameter to convert binary to decimal numbers.

  • Step 4.1 − In the bToD() function, define the ‘currentBase’ variable and initialize it with 1.

  • Step 4.2 − Use the for loop, and iterate through the string from the last index.

  • Step 4.3 − In the for loop, if the current character is equal to ‘1’, we need to add the currentBase value to the ‘decimal_number’.

  • Step 4.4 − Multiply the currentBase by 2.

  • Step 5 − Insert the decimal number in the ‘allNumber’ set.

  • Step 6 − Use the next_permutation() method in the condition of the do-while loop, as it returns true if the next permutation of the string exists.

  • Step 7 − Print all numbers added in the ‘allNumbers’ to get a unique decimal number related to all permutations of a given binary string.

Example

#include <iostream>
#include <algorithm>
#include <set>

using namespace std;
int bToD(string num){
   int decimal_number = 0;
   // Initializing base value to 1, and it increases by power of 2 in each iteration
   int currentBase = 1;
   for (int i = num.length() - 1; i >= 0; i--){
      if (num[i] == '1'){
         decimal_number += currentBase;
      }
      currentBase = currentBase * 2;
   }
   return decimal_number;
}
void getDecimalPermutations(string str){
   // create set
   set<int> allNumbers;
   // sort the string
   sort(str.begin(), str.end());
   do {
      // convert binary string to decimal
      int result = bToD(str);
      // insert the decimal number to set
      allNumbers.insert(result);
      // get the next permutation
   } while (next_permutation(str.begin(), str.end()));
   //Print all distinct decimal numbers
   cout << "All decimal numbers which we can achieve using permutations are " << endl;
   for (auto num : allNumbers)
      cout << num << " ";
      cout << endl;
}
int main(){
   string bString = "101";
   getDecimalPermutations(bString);
   return 0;
}

Output

All decimal numbers which we can achieve using permutations are 
3 5 6
  • Time complexity − O(n*n!). Here, next_permutations() takes O(n) time to find one permutation, and we are finding total n! Permutations.

  • Space complexity − O(n!), as we store all permutations in the list.

Conclusion

We learned different approaches to get unique decimal values obtained by all permutations of a given binary string. In the first approach, we used backtracking; in the second approach, we used the next_permutation() method.

The second approach's code is clearer, but it takes more time and complexity.

Updated on: 18-Jul-2023

197 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements