给定整数N ,任务是找到恰好有两个设置位的第N个自然数。
例子:
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.
天真的方法:有关此问题的最简单解决方案,请参阅本文的上一篇文章。
时间复杂度: O(N)
辅助空间: O(1)
高效方法:为了优化上述方法,使用二进制搜索来查找第N个数字的想法。请按照以下步骤解决问题:
- 给定序列中的任何数字均采用(2 a + 2 b )形式,其中a> b 。
- 可以通过识别值a和b来识别系列中的第N个项。
- 查找使得(a *(A + 1))/ 2≥N的值,并保持一个约束,一个必须为最小
- 因此,找到一个在使用二进制搜索上面的步骤限制值。
- 完成上述步骤后,使用a和N查找b的值,并将结果打印为(2 a + 2 b ) 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the Nth number
// with exactly two bits set
void findNthNum(long long int N)
{
// Initialize variables
long long int a, b, left;
long long int right, mid;
long long int t, last_num = 0;
// Initialize the range in which
// the value of 'a' is present
left = 1, right = N;
// Perform Binary Search
while (left <= right) {
// Find the mid value
mid = left + (right - left) / 2;
t = (mid * (mid + 1)) / 2;
// Update the range using the
// mid value t
if (t < N) {
left = mid + 1;
}
else if (t == N) {
a = mid;
break;
}
else {
a = mid;
right = mid - 1;
}
}
// Find b value using a and N
t = a - 1;
b = N - (t * (t + 1)) / 2 - 1;
// Print the value 2^a + 2^b
cout << (1 << a) + (1 << b);
}
// Driver Code
int main()
{
long long int N = 15;
// Function Call
findNthNum(N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the Nth number
// with exactly two bits set
static void findNthNum(int N)
{
// Initialize variables
int a = 0, b, left;
int right, mid;
int t, last_num = 0;
// Initialize the range in which
// the value of 'a' is present
left = 1;
right = N;
// Perform Binary Search
while (left <= right) {
// Find the mid value
mid = left + (right - left) / 2;
t = (mid * (mid + 1)) / 2;
// Update the range using the
// mid value t
if (t < N) {
left = mid + 1;
}
else if (t == N) {
a = mid;
break;
}
else {
a = mid;
right = mid - 1;
}
}
// Find b value using a and N
t = a - 1;
b = N - (t * (t + 1)) / 2 - 1;
// Print the value 2^a + 2^b
System.out.print((1 << a) + (1 << b));
}
// Driver Code
public static void main(String[] args)
{
int N = 15;
// Function Call
findNthNum(N);
}
}
// This code contributed by shikhasingrajput
Python3
# Python3 program for the above approach
# Function to find the Nth number
# with exactly two bits set
def findNthNum(N):
# Initialize variables
last_num = 0
# Initialize the range in which
# the value of 'a' is present
left = 1
right = N
# Perform Binary Search
while (left <= right):
# Find the mid value
mid = left + (right - left) // 2
t = (mid * (mid + 1)) // 2
# Update the range using the
# mid value t
if (t < N):
left = mid + 1
elif (t == N):
a = mid
break
else:
a = mid
right = mid - 1
# Find b value using a and N
t = a - 1
b = N - (t * (t + 1)) // 2 - 1
# Print the value 2^a + 2^b
print((1 << a) + (1 << b))
# Driver Code
if __name__ == "__main__":
N = 15
# Function Call
findNthNum(N)
# This code is contributed by chitranayal
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the Nth number
// with exactly two bits set
static void findNthNum(int N)
{
// Initialize variables
int a = 0, b, left;
int right, mid;
int t;
//int last_num = 0;
// Initialize the range in which
// the value of 'a' is present
left = 1; right = N;
// Perform Binary Search
while (left <= right)
{
// Find the mid value
mid = left + (right - left) / 2;
t = (mid * (mid + 1)) / 2;
// Update the range using the
// mid value t
if (t < N)
{
left = mid + 1;
}
else if (t == N)
{
a = mid;
break;
}
else
{
a = mid;
right = mid - 1;
}
}
// Find b value using a and N
t = a - 1;
b = N - (t * (t + 1)) / 2 - 1;
// Print the value 2^a + 2^b
Console.Write((1 << a) + (1 << b));
}
// Driver Code
public static void Main()
{
int N = 15;
// Function Call
findNthNum(N);
}
}
// This code is contributed by sanjoy_62
输出:
48
时间复杂度: O(log N)
辅助空间: O(1)