给定正整数N ,任务是找出从0到N的所有连续位差之和。
注意:如果两个(例如(3,4))的位长度不同,则在开头(011,100)后面附加0。
例子:
Input: N = 3
Output: 4
Explanation:
Bit differences of (0, 1) + (1, 2) + (2, 3) = 1 + 2 + 1 = 4.
Input: N = 7
Output: 11
天真的方法:
最简单的方法是按位比较范围内的两个连续值,并找出这两个数字相差多少位。将此差值加到总和上。这样获得的最终总和是所需的解决方案。
时间复杂度: O(N)
方法:
为了优化上述解决方案,需要进行以下观察:
- 连续的数字位差遵循一种模式,即每个等于(2 i )的值X与先前的数字和(2 i – 1)数在X和(2 i之上)的位差为(i +1)。 – 1)X以下的数字遵循相同的模式。
- 对于X = 4(2 2 ),i = 2的位差为(2 +1),数字(1、2、3)和(5、6、7)遵循相同的位差模式。
For X = 4, the pattern is as follows:
NUM BIT Diff
1 1(0, 1)
2 2(1, 2)
3 1(2, 3)
4 3(3, 4)
5 1(4, 5)
6 2(5, 6)
7 1(6, 7)
请按照以下步骤解决问题:
- 对于每个N ,找到小于或等于N的最接近的数字,即2的幂。假设该数字为M。
- 对于所有小于M的数字,可以使用以下递归方法找出连续位差的总和。
Count(i) = (i + 1) + 2 * Count(i – 1)
where i is the exponent of the nearest power of 2.
- 初始化大小为65(基于0的索引)的数组,以存储使用递归函数Count()时获得的值,以便将来,如果需要相同的Count()值,则可以直接获取它们而无需递归调用Count()函数以节省时间。
- 使用以下公式,对大于M的剩余数重复相同的过程。
Sum = Sum + (i+1) + Count(i-1)
例如:
对于N = 10,使用Count(3)计算最接近的2的幂,即M = 8,然后对剩余的大于8的数重复该过程。
下面是上述方法的实现:
C++
// C++ program for the above problem
#include
using namespace std;
long long a[65] = { 0 };
// Recursive function to count
// the sum of bit differences
// of numbers from 1 to
// pow(2, (i+1)) - 1
long long Count(int i)
{
// base cases
if (i == 0)
return 1;
else if (i < 0)
return 0;
// Recursion call if the sum
// of bit difference of numbers
// around i are not calculated
if (a[i] == 0) {
a[i] = (i + 1) + 2 * Count(i - 1);
return a[i];
}
// return the sum of bit
// differences if already
// calculated
else
return a[i];
}
// Function to calculate the
// sum of bit differences up to N
long long solve(long long n)
{
long long i, sum = 0;
while (n > 0) {
// nearest smaller power
// of 2
i = log2(n);
// remaining numbers
n = n - pow(2, i);
// calculate the count
// of bit diff
sum = sum + (i + 1) + Count(i - 1);
}
return sum;
}
// Driver code
int main()
{
long long n = 7;
cout << solve(n) << endl;
return 0;
}
Java
// Java program for the above problem
import java.util.*;
class GFG{
static int a[] = new int[65];
// Recursive function to count
// the sum of bit differences
// of numbers from 1 to
// pow(2, (i+1)) - 1
static int Count(int i)
{
// base cases
if (i == 0)
return 1;
else if (i < 0)
return 0;
// Recursion call if the sum
// of bit difference of numbers
// around i are not calculated
if (a[i] == 0)
{
a[i] = (i + 1) + 2 * Count(i - 1);
return a[i];
}
// return the sum of bit
// differences if already
// calculated
else
return a[i];
}
// Function to calculate the
// sum of bit differences up to N
static int solve(int n)
{
int i, sum = 0;
while (n > 0)
{
// nearest smaller power
// of 2
i = (int)(Math.log(n) / Math.log(2));
// remaining numbers
n = n - (int)Math.pow(2, i);
// calculate the count
// of bit diff
sum = sum + (i + 1) + Count(i - 1);
}
return sum;
}
// Driver code
public static void main(String[] args)
{
int n = 7;
System.out.println(solve(n));
}
}
// This code is contributed by rock_cool
Python3
# Python3 program for the above problem
import math
a = [0] * 65
# Recursive function to count
# the sum of bit differences
# of numbers from 1 to
# pow(2, (i+1)) - 1
def Count(i):
# Base cases
if (i == 0):
return 1
elif (i < 0):
return 0
# Recursion call if the sum
# of bit difference of numbers
# around i are not calculated
if (a[i] == 0):
a[i] = (i + 1) + 2 * Count(i - 1)
return a[i]
# Return the sum of bit
# differences if already
# calculated
else:
return a[i]
# Function to calculate the
# sum of bit differences up to N
def solve(n):
sum = 0
while (n > 0):
# Nearest smaller power
# of 2
i = int(math.log2(n))
# Remaining numbers
n = n - pow(2, i)
# Calculate the count
# of bit diff
sum = sum + (i + 1) + Count(i - 1)
return sum
# Driver code
n = 7
print(solve(n))
# This code is contributed by sanjoy_62
C#
// C# program for the above problem
using System;
class GFG{
static int []a = new int[65];
// Recursive function to count
// the sum of bit differences
// of numbers from 1 to
// pow(2, (i+1)) - 1
static int Count(int i)
{
// base cases
if (i == 0)
return 1;
else if (i < 0)
return 0;
// Recursion call if the sum
// of bit difference of numbers
// around i are not calculated
if (a[i] == 0)
{
a[i] = (i + 1) + 2 * Count(i - 1);
return a[i];
}
// return the sum of bit
// differences if already
// calculated
else
return a[i];
}
// Function to calculate the
// sum of bit differences up to N
static int solve(int n)
{
int i, sum = 0;
while (n > 0)
{
// nearest smaller power
// of 2
i = (int)(Math.Log(n) / Math.Log(2));
// remaining numbers
n = n - (int)Math.Pow(2, i);
// calculate the count
// of bit diff
sum = sum + (i + 1) + Count(i - 1);
}
return sum;
}
// Driver code
public static void Main(String[] args)
{
int n = 7;
Console.Write(solve(n));
}
}
// This code is contributed by shivanisinghss2110
Javascript
输出:
11
时间复杂度: O(log(N))
辅助空间: O(1)