Given an integer N, the task is to find the Nth natural number with exactly two set bits.
Examples:
Input: N = 4
Output: 9
Explanation: Numbers with exactly two set bits are 3, 5, 6, 9, 10, 12, ….
The 4th term in this series is 9.
Input: N = 15
Output: 48
Explanation: Numbers with exactly two set bits are 3, 5, 6, 9, 10, 12, 17, 18, 20, 24, 33, 34, 36, 40, 48….
The 15th term in this series is 48.
Naive Approach: Refer to the previous post of this article for the simplest solution possible for this problem.
Time Complexity: O(N)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea to use Binary Search to find the Nth number. Follow the steps below to solve the problem:
- Any number in the given series is in the form (2a + 2b) where a > b.
- The Nth term in a series can be identified by identifying values a and b.
- Find the value of a such that (a * (a + 1)) / 2 ? N and keeping a constraint that a must be minimum
- Therefore, find the value of a for constraints in the above steps using Binary Search.
- After the above steps, find the value of b using a and N and print the result as (2a + 2b).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findNthNum( long long int N)
{
long long int a, b, left;
long long int right, mid;
long long int t, last_num = 0;
left = 1, right = N;
while (left <= right) {
mid = left + (right - left) / 2;
t = (mid * (mid + 1)) / 2;
if (t < N) {
left = mid + 1;
}
else if (t == N) {
a = mid;
break ;
}
else {
a = mid;
right = mid - 1;
}
}
t = a - 1;
b = N - (t * (t + 1)) / 2 - 1;
cout << (1 << a) + (1 << b);
}
int main()
{
long long int N = 15;
findNthNum(N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void findNthNum( int N)
{
int a = 0 , b, left;
int right, mid;
int t, last_num = 0 ;
left = 1 ;
right = N;
while (left <= right) {
mid = left + (right - left) / 2 ;
t = (mid * (mid + 1 )) / 2 ;
if (t < N) {
left = mid + 1 ;
}
else if (t == N) {
a = mid;
break ;
}
else {
a = mid;
right = mid - 1 ;
}
}
t = a - 1 ;
b = N - (t * (t + 1 )) / 2 - 1 ;
System.out.print(( 1 << a) + ( 1 << b));
}
public static void main(String[] args)
{
int N = 15 ;
findNthNum(N);
}
}
|
Python3
def findNthNum(N):
last_num = 0
left = 1
right = N
while (left < = right):
mid = left + (right - left) / / 2
t = (mid * (mid + 1 )) / / 2
if (t < N):
left = mid + 1
elif (t = = N):
a = mid
break
else :
a = mid
right = mid - 1
t = a - 1
b = N - (t * (t + 1 )) / / 2 - 1
print (( 1 << a) + ( 1 << b))
if __name__ = = "__main__" :
N = 15
findNthNum(N)
|
C#
using System;
class GFG{
static void findNthNum( int N)
{
int a = 0, b, left;
int right, mid;
int t;
left = 1; right = N;
while (left <= right)
{
mid = left + (right - left) / 2;
t = (mid * (mid + 1)) / 2;
if (t < N)
{
left = mid + 1;
}
else if (t == N)
{
a = mid;
break ;
}
else
{
a = mid;
right = mid - 1;
}
}
t = a - 1;
b = N - (t * (t + 1)) / 2 - 1;
Console.Write((1 << a) + (1 << b));
}
public static void Main()
{
int N = 15;
findNthNum(N);
}
}
|
Javascript
<script>
function findNthNum(N)
{
let a = 0, b, left;
let right, mid;
let t, last_num = 0;
left = 1;
right = N;
while (left <= right) {
mid = left + (right - left) / 2;
t = (mid * (mid + 1)) / 2;
if (t < N) {
left = mid + 1;
}
else if (t == N) {
a = mid;
break ;
}
else {
a = mid;
right = mid - 1;
}
}
t = a - 1;
b = N - (t * (t + 1)) / 2 - 1;
document.write((1 << a) + (1 << b));
}
let N = 15;
findNthNum(N);
</script>
|
Time Complexity: O(log N)
Auxiliary Space: O(1)