给定数字N ,任务是为从0到N的每个连续数字计算二进制表示形式中相应不同位的总数。
例子:
Input: N = 5
Output: 8
Explanation:
Binary Representation of numbers are:
0 -> 000,
1 -> 001,
2 -> 010,
3 -> 011,
4 -> 100,
5 -> 101
Between 1 and 0 -> 1 bit is different
Between 2 and 1 -> 2 bits are different
Between 3 and 2 -> 1 bit is different
Between 4 and 3 -> 3 bits are different
Between 5 and 4 -> 1 bit is different
Total = 1 + 2 + 1 + 3 + 1 = 8
Input: N = 11
Output: 19
天真的方法:这个想法是从0到N进行迭代,对于每对连续的元素,使用本文讨论的方法为每对元素找到不同的位数。
时间复杂度: O(N * log N)
辅助空间: (1)
高效的方法:对于高效的方法,我们必须注意以下几点:
number: 1 2 3 4 5 6 7 8
bit_diff: 1 2 1 3 1 2 1 4
sum_diff: 1 3 4 7 8 10 11 15
通过以上计算,我们可以观察到以下内容:
- 如果N是2的理想幂,则从0到N的相应不同比特的总和由下式给出:
sum_diff = (2x+1-1)
where x = log2(N) - 如果N不是2的完美幂,则可以将其表示为2的完美幂:
N = 2a + 2b + … + 2x
因此,从0到N的相应不同比特的总和可以计算为:
sum_diff = (2a+1-1) + (2b+1-1) + … + (2x+1-1).
举些例子:
If N = 8, then
The binary representation of 8 is “1000”
Hence 11 = 23
total count = (23+1 – 1)
total count = 8 – 1 = 7.
If N = 11, then
The binary representation of 11 is “1011”
Hence 11 = 23 + 21 + 20
=> total count = (23+1 – 1) + (21+1 – 1) + (20+1 – 1)
=> total count = 15 + 3 + 1 = 19.
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to implement fast
// exponentiation
int binpow(int a, int b)
{
int res = 1;
while (b) {
if (b & 1)
res = res * a;
a = a * a;
b /= 2;
}
return res;
}
// Function to return the value
// for powers of 2
int find(int x)
{
if (x == 0)
return 0;
int p = log2(x);
return binpow(2, p + 1) - 1;
}
// Function to convert N into binary
string getBinary(int n)
{
// To store binary representation
string ans = "";
// Iterate each digit of n
while (n) {
int dig = n % 2;
ans += to_string(dig);
n /= 2;
}
// Return binary representation
return ans;
}
// Function to find difference in bits
int totalCountDifference(int n)
{
// Get binary representation
string ans = getBinary(n);
// total number of bit
// differences from 0 to N
int req = 0;
// Iterate over each binary bit
for (int i = 0; i < ans.size(); i++) {
// If current bit is '1' then add
// the count of current bit
if (ans[i] == '1') {
req += find(binpow(2, i));
}
}
return req;
}
// Driver Code
int main()
{
// Given Number
int N = 5;
// Function Call
cout << totalCountDifference(N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.Math;
class GFG{
// Function to implement fast
// exponentiation
static int binpow(int a, int b)
{
int res = 1;
while (b > 0)
{
if (b % 2 == 1)
res = res * a;
a = a * a;
b /= 2;
}
return res;
}
// Function to return the
// value for powers of 2
static int find(int x)
{
if (x == 0)
return 0;
int p = (int)(Math.log(x) / Math.log(2));
return binpow(2, p + 1) - 1;
}
// Function to convert N into binary
static String getBinary(int n)
{
// To store the binary representation
String ans = "";
// Iterate each digit of n
while (n > 0)
{
int dig = n % 2;
ans += dig;
n /= 2;
}
// Return binary representation
return ans;
}
// Function to find difference in bits
static int totalCountDifference(int n)
{
// Get binary representation
String ans = getBinary(n);
// total number of bit
// differences from 0 to N
int req = 0;
// Iterate over each binary bit
for(int i = 0; i < ans.length(); i++)
{
// If current bit is '1' then add
// the count of current bit
if (ans.charAt(i) == '1')
{
req += find(binpow(2, i));
}
}
return req;
}
// Driver code
public static void main (String[] args)
{
// Given number
int n = 5;
System.out.print(totalCountDifference(n));
}
}
// This code is contributed by spp____
Python3
# Python3 program for the above approach
from math import log
# Function to implement fast
# exponentiation
def binpow(a, b):
res = 1
while (b > 0):
if (b % 2 == 1):
res = res * a
a = a * a
b //= 2
return res
# Function to return the value
# for powers of 2
def find(x):
if (x == 0):
return 0
p = log(x) / log(2)
return binpow(2, p + 1) - 1
# Function to convert N into binary
def getBinary(n):
# To store binary representation
ans = ""
# Iterate each digit of n
while (n > 0):
dig = n % 2
ans += str(dig)
n //= 2
# Return binary representation
return ans
# Function to find difference in bits
def totalCountDifference(n):
# Get binary representation
ans = getBinary(n)
# total number of bit
# differences from 0 to N
req = 0
# Iterate over each binary bit
for i in range(len(ans)):
# If current bit is '1' then add
# the count of current bit
if (ans[i] == '1'):
req += find(binpow(2, i))
return req
# Driver Code
# Given Number
N = 5
# Function Call
print(totalCountDifference(N))
# This code is contributed by shubhamsingh10
C#
// C# program for the above approach
using System;
class GFG{
// Function to implement fast
// exponentiation
static int binpow(int a, int b)
{
int res = 1;
while (b > 0)
{
if (b % 2 == 1)
res = res * a;
a = a * a;
b /= 2;
}
return res;
}
// Function to return the
// value for powers of 2
static int find(int x)
{
if (x == 0)
return 0;
int p = (int)(Math.Log(x) / Math.Log(2));
return binpow(2, p + 1) - 1;
}
// Function to convert N into binary
static String getBinary(int n)
{
// To store the binary representation
String ans = "";
// Iterate each digit of n
while (n > 0)
{
int dig = n % 2;
ans += dig;
n /= 2;
}
// Return binary representation
return ans;
}
// Function to find difference in bits
static int totalCountDifference(int n)
{
// Get binary representation
string ans = getBinary(n);
// total number of bit
// differences from 0 to N
int req = 0;
// Iterate over each binary bit
for(int i = 0; i < ans.Length; i++)
{
// If current bit is '1' then add
// the count of current bit
if (ans[i] == '1')
{
req += find(binpow(2, i));
}
}
return req;
}
// Driver code
public static void Main()
{
// Given number
int n = 5;
Console.Write(totalCountDifference(n));
}
}
// This code is contributed by Nidhi_biet
8
时间复杂度: O((log N) 2 )
辅助空间: (1)