Open In App

Maximum set bit count from pairs of integers from 0 to N that yields a sum as N

Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer N, the task is to find the maximum frequency of set bits among all pairs of integers from 0 to N that yields a sum as N.

Examples:

Input: N = 5
Output: 3
Explanation: 
All the pairs are {0, 5}, {1, 4}, {2, 3} which has a sum as 5.
0 (0000) and 5 (0101), number of set bit = 2
1 (0001) and 4 (0100), number of set bit = 2
2 (0010) and 3 (0011), number of set bit = 3, hence 3 is the maximum.

Input: N = 11
Output: 4
Explanation:
All the pairs are {0, 11}, {1, 10}, {2, 9}, {3, 8}, {4, 7}, {5, 6} and the maximum ans will be for the pair {4, 7}  
4 = 1000 and 7 = 0111, total number of set bits=1+3=4

Naive Approach: The simplest way to solve this problem is to generate all possible pairs with sum N and compute the maximum sum of the set bits of all such pairs, and print the maximum no of set bits sum.

Time Complexity: O(N * log N)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized through these steps:

  • Find a number less than equal to N whose all the bits from the Least significant bit to the Most significant bit are set bits. That number will be the first number in the pair.
  • Compute the number of set bits the pair {first, N-first} and sum it up.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the first number
int create_first_no(int n)
{
    // Length of the binary from
    int length = 0;
 
    // Number of set bits
    int freq_set_bits = 0;
    int ans = 0;
    while (n) {
 
        // Update the first number
        ans = ans << 1;
        ans = ans + 1;
 
        // Increment length
        length++;
 
        // Update the frequency
        if ((n & 1))
            freq_set_bits += 1;
 
        n = n >> 1;
    }
    // Check if n does not have all the
    // bits as set bits then make
    // the first as less than n
    if (length != freq_set_bits)
        ans = (ans >> 1);
 
    // Return the first value
    return ans;
}
 
// Function to calculate maximum
// set bit frequency sum
int maxSetBits(int n)
{
    // First value of pair
    int first = create_first_no(n);
 
    // Second value of pair
    int second = n - first;
 
    // __builtin_popcount() is inbuilt
    // function to count the number of set bits
    int freq_first
        = __builtin_popcount(first);
    int freq_second
        = __builtin_popcount(second);
 
    // Return the sum of freq of setbits
    return freq_first + freq_second;
}
 
// Driver Code
int main()
{
    int N = 5;
 
    // Function call
    cout << maxSetBits(N);
    return 0;
}


Java




// Java program to implement the
// above approach
import java.util.*;
 
class GFG {
 
// Function to find the first number
static int create_first_no(int n)
{
     
    // Length of the binary from
    int length = 0;
 
    // Number of set bits
    int freq_set_bits = 0;
    int ans = 0;
     
    while (n != 0)
    {
 
        // Update the first number
        ans = ans << 1;
        ans = ans + 1;
 
        // Increment length
        length++;
 
        // Update the frequency
        if ((n & 1) == 1)
            freq_set_bits += 1;
 
        n = n >> 1;
    }
     
    // Check if n does not have all the
    // bits as set bits then make
    // the first as less than n
    if (length != freq_set_bits)
        ans = (ans >> 1);
 
    // Return the first value
    return ans;
}
 
// Function to calculate maximum
// set bit frequency sum
static int maxSetBits(int n)
{
     
    // First value of pair
    int first = create_first_no(n);
 
    // Second value of pair
    int second = n - first;
 
    // Integer.bitCount() is inbuilt
    // function to count the number of set bits
    int freq_first = Integer.bitCount(first);
    int freq_second = Integer.bitCount(second);
 
    // Return the sum of freq of setbits
    return freq_first + freq_second;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 5;
     
    // Function call
    System.out.println(maxSetBits(N));
}
}
 
// This code is contributed by offbeat


Python3




# Python3 program for the
# above approach
 
# Function to find the
# first number
def create_first_no(n):
 
    # Length of the binary
    # from
    length = 0
 
    # Number of set bits
    freq_set_bits = 0
    ans = 0
    while (n != 0):
 
        # Update the first number
        ans = ans << 1
        ans = ans + 1
 
        # Increment length
        length += 1
 
        # Update the frequency
        if ((n & 1) != 0):
            freq_set_bits += 1
 
        n = n >> 1
 
    # Check if n does not have
    # all the bits as set bits
    # then make the first as
    # less than n
    if (length != freq_set_bits):
        ans = (ans >> 1)
 
    # Return the first value
    return ans
 
# Function to calculate maximum
# set bit frequency sum
def maxSetBits(n):
 
    # First value of pair
    first = create_first_no(n)
 
    # Second value of pair
    second = n - first
 
    # __builtin_popcount() is
    # inbuilt function to count
    # the number of set bits
    freq_first = bin(first).count('1')
    freq_second = bin(second).count('1')
 
    # Return the sum of
    # freq of setbits
    return (freq_first +
            freq_second)
 
# Driver code
N = 5
 
# Function call
print(maxSetBits(N))
 
# This code is contributed by divyeshrabadiya07


C#




// C# program to implement the
// above approach
using System;
using System.Linq;
class GFG {
  
// Function to find the first number
static int create_first_no(int n)
{
      
    // Length of the binary from
    int length = 0;
  
    // Number of set bits
    int freq_set_bits = 0;
    int ans = 0;
      
    while (n != 0)
    {
  
        // Update the first number
        ans = ans << 1;
        ans = ans + 1;
  
        // Increment length
        length++;
  
        // Update the frequency
        if ((n & 1) == 1)
            freq_set_bits += 1;
  
        n = n >> 1;
    }
      
    // Check if n does not have all the
    // bits as set bits then make
    // the first as less than n
    if (length != freq_set_bits)
        ans = (ans >> 1);
  
    // Return the first value
    return ans;
}
public static int countSetBits(int n)
{
 
  // base case
  if (n == 0)
    return 0;
 
  else
 
    // if last bit set
    // add 1 else add 0
    return (n & 1) + countSetBits(n >> 1);
}
 
// Function to calculate maximum
// set bit frequency sum
static int maxSetBits(int n)
{
      
    // First value of pair
    int first = create_first_no(n);
  
    // Second value of pair
    int second = n - first;
  
    //countSetBits function to
    //count the number of set bits
    int freq_first = countSetBits(first);
    int freq_second = countSetBits(second);
  
    // Return the sum of freq of setbits
    return freq_first + freq_second;
}
  
// Driver code
public static void Main(string[] args)
{
    int N = 5;
      
    // Function call
    Console.Write(maxSetBits(N));
}
}
  
// This code is contributed by Ritik Bansal


Javascript




<script>
 
// Javascript program for
// the above approach
 
// Function to find the first number
function create_first_no(n)
{
       
    // Length of the binary from
    let length = 0;
   
    // Number of set bits
    let freq_set_bits = 0;
    let ans = 0;
       
    while (n != 0)
    {
   
        // Update the first number
        ans = ans << 1;
        ans = ans + 1;
   
        // Increment length
        length++;
   
        // Update the frequency
        if ((n & 1) == 1)
            freq_set_bits += 1;
   
        n = n >> 1;
    }
       
    // Check if n does not have all the
    // bits as set bits then make
    // the first as less than n
    if (length != freq_set_bits)
        ans = (ans >> 1);
   
    // Return the first value
    return ans;
}
function countSetBits(n)
{
  
  // base case
  if (n == 0)
    return 0;
  
  else
  
    // if last bit set
    // add 1 else add 0
    return (n & 1) + countSetBits(n >> 1);
}
  
// Function to calculate maximum
// set bit frequency sum
function maxSetBits(n)
{
       
    // First value of pair
    let first = create_first_no(n);
   
    // Second value of pair
    let second = n - first;
   
    //countSetBits function to
    //count the number of set bits
    let freq_first = countSetBits(first);
    let freq_second = countSetBits(second);
   
    // Return the sum of freq of setbits
    return freq_first + freq_second;
}
     
// Driver Code
     
   let N = 5;
       
    // Function call
    document.write(maxSetBits(N));
 
</script>


Output: 

3

 

Time Complexity: O(logN)
Auxiliary Space: O(1)



Last Updated : 10 May, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads