Open In App

Minimum number of distinct powers of 2 required to express a given binary number

Last Updated : 19 May, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a binary string S, the task is to find the minimum number of Powers of 2 required to express a S.
Examples: 
 

Input: S = "111" 
Output:
Explanation: 
Two possible representations of "111" (= 7) using powers of 2 are: 
20 + 21 + 22 = 1 + 2 + 4 = 7 
23 - 20 = 8 - 1 = 7 
Therefore, the minimum powers of 2 required to represent S is 2.
Input: S = "1101101" 
Output:
Explanation: 
1101101 can be represented as 27 - 24 - 22 + 20.


Approach: 
The key observation to solve this problem is that we can replace any consecutive sequence of 1 by using only two powers of 2
 

Illustration: 
S = "1001110" 
The sequence of 3 consecutive 1's, "1110" can be expressed as 24 - 21 
Therefore, the given str


Follow the steps below to solve the problem: 
 

  • Reverse the string S.
  • Iterate over the string S.
  • Replace every substring of 1's lying within indices [L, R] by placing 1 at R+1 and -1 at L.
  • Once the entire string is traversed, count the number of non-zero values in the string as the required answer.


Below is the implementation of the above approach: 
 

C++
// C++ Program to implement the
// above approach
#include <bits/stdc++.h>
using namespace std;

// Function to return the minimum
// distinct powers of 2 required
// to express s
void findMinimum(string s)
{
    int n = s.size();

    int x[n + 1] = { 0 };

    // Reverse the string to
    // start from lower powers
    reverse(s.begin(), s.end());

    for (int i = 0; i < n; i++) {

        // Check if the character is 1
        if (s[i] == '1') {

            if (x[i] == 1) {
                x[i + 1] = 1;
                x[i] = 0;
            }

            // Add in range provided range
            else if (i and x[i - 1] == 1) {
                x[i + 1] = 1;
                x[i - 1] = -1;
            }

            else
                x[i] = 1;
        }
    }

    // Initialize the counter
    int c = 0;

    for (int i = 0; i <= n; i++) {

        // Check if the character
        // is not 0
        if (x[i] != 0)

            // Increment the counter
            c++;
    }

    // Print the result
    cout << c << endl;
}

// Driver Code
int main()
{
    string str = "111";

    findMinimum(str);

    return 0;
}
Java
// Java program to implement the
// above approach
import java.util.*;

class GFG{

// Function to return the minimum
// distinct powers of 2 required
// to express s
static void findMinimum(String s)
{
    int n = s.length();
    int[] x = new int[n + 1];
    
    StringBuilder s2 = new StringBuilder(s);
    
    // Reverse the string to
    // start from lower powers
    s2.reverse();
    
    String s3 = s2.toString();

    for(int i = 0; i < n; i++)
    {

        // Check if the character is 1
        if (s3.charAt(i) == '1')
        {
            if (x[i] == 1)
            {
                x[i + 1] = 1;
                x[i] = 0;
            }

            // Add in range provided range
            else if (1 <= i && (i & x[i - 1]) == 1) 
            {
                x[i + 1] = 1;
                x[i - 1] = -1;
            }
            else
                x[i] = 1;
        }
    }

    // Initialize the counter
    int c = 0;

    for(int i = 0; i <= n; i++)
    {

        // Check if the character
        // is not 0
        if (x[i] != 0)

            // Increment the counter
            c++;
    }
    
    // Print the result
    System.out.println(c);
}

// Driver code
public static void main(String[] args)
{
    String str = "111";

    findMinimum(str);
}
}

// This code is contributed by offbeat
Python3
# Python3 program to implement the 
# above approach 

# Function to return the minimum
# distinct powers of 2 required
# to express s
def findMinimum(s):

    n = len(s)
    x = [0] * (n + 1)

    # Reverse the string to
    # start from lower powers
    s = s[::-1]
    
    for i in range(n):
        
        # Check if the character is 1
        if(s[i] == '1'):
            if(x[i] == 1):
                x[i + 1] = 1
                x[i] = 0

            # Add in range provided range
            elif(i and x[i - 1] == 1):
                x[i + 1] = 1
                x[i - 1] = -1

            else:
                x[i] = 1

    # Initialize the counter
    c = 0

    for i in range(n + 1):

        # Check if the character
        # is not 0
        if(x[i] != 0):

            # Increment the counter 
            c += 1

    # Print the result
    print(c)

# Driver Code
if __name__ == '__main__':

    str = "111"
    
    # Function Call
    findMinimum(str)

# This code is contributed by Shivam Singh
C#
// C# program to implement the
// above approach
using System;
using System.Text;

class GFG{

// Function to return the minimum
// distinct powers of 2 required
// to express s
static void findMinimum(String s)
{
    int n = s.Length;
    int[] x = new int[n + 1];
    
    StringBuilder s2 = new StringBuilder(s);
    
    // Reverse the string to
    // start from lower powers
    s2 = reverse(s2.ToString());
    
    String s3 = s2.ToString();

    for(int i = 0; i < n; i++)
    {
        
        // Check if the character is 1
        if (s3[i] == '1')
        {
            if (x[i] == 1)
            {
                x[i + 1] = 1;
                x[i] = 0;
            }

            // Add in range provided range
            else if (1 <= i && (i & x[i - 1]) == 1) 
            {
                x[i + 1] = 1;
                x[i - 1] = -1;
            }
            else
                x[i] = 1;
        }
    }

    // Initialize the counter
    int c = 0;

    for(int i = 0; i <= n; i++)
    {
        
        // Check if the character
        // is not 0
        if (x[i] != 0)

            // Increment the counter
            c++;
    }
    
    // Print the result
    Console.WriteLine(c);
}

static StringBuilder reverse(String input)
{
    char[] a = input.ToCharArray();
    int l, r = a.Length - 1;
    
    for(l = 0; l < r; l++, r--)
    {
        char temp = a[l];
        a[l] = a[r];
        a[r] = temp;
    }
    return new StringBuilder(String.Join("", a));
}

// Driver code
public static void Main(String[] args)
{
    String str = "111";

    findMinimum(str);
}
}

// This code is contributed by Rohit_ranjan 
JavaScript
<script>
 

// Javascript Program to implement the
// above approach

// Function to return the minimum
// distinct powers of 2 required
// to express s
function findMinimum(s)
{
    var n = s.length;

    var x = Array(n+1).fill(0);

    // Reverse the string to
    // start from lower powers
    s.reverse();

    for (var i = 0; i < n; i++) {

        // Check if the character is 1
        if (s[i] == '1') {

            if (x[i] == 1) {
                x[i + 1] = 1;
                x[i] = 0;
            }

            // Add in range provided range
            else if (i && x[i - 1] == 1) {
                x[i + 1] = 1;
                x[i - 1] = -1;
            }

            else
                x[i] = 1;
        }
    }

    // Initialize the counter
    var c = 0;

    for (var i = 0; i <= n; i++) {

        // Check if the character
        // is not 0
        if (x[i] != 0)

            // Increment the counter
            c++;
    }

    // Print the result
    document.write( c );
}

// Driver Code
var str = "111".split('');
findMinimum(str);

</script>  

Output: 
2

 

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


Next Article

Similar Reads