[英]Adding all numbers from 1 to N which have number of set bits as 2
I have a question where I have to add numbers from 1 to N which have their set bits as 2. Like for N = 5 we should get value 8, as number 3 and 5 have 2 bits set to one. 我有一个问题,我必须添加从1到N的数字,它们的设置位为2。像N = 5一样,我们应该得到值8,因为数字3和5的2位设置为1。 I am implementing the same in java. 我在Java中实现相同。 I am getting the o/p correct for int value but when it comes to the long values, either it's taking a lot of time or freezing, and when I submit the same on code judge sites, it's giving run time exceeded message. 我得到了正确的int值的o / p值,但是当涉及到长值时,这会花费很多时间或冻结,而当我在代码判断站点上提交该值时,则会给出运行时间超出消息。 Please guide me how may I optimise my code to run it faster, thanks :) 请指导我如何优化代码以更快地运行它,谢谢:)
public static void main(String[] args)
{
long n = 1000000L;
long sum = 0;
long start = System.currentTimeMillis();
for(long i = 1L ; i <= n ; i++)
{
if(Long.bitCount(i) == 2)
{
sum += i;
}
}
long end = System.currentTimeMillis();
System.out.println(sum);
System.out.println("time="+(end-start));
}
As @hbejgel notes, there is no point in looping over all numbers and checking their bit count. 正如@hbejgel指出的那样,循环遍历所有数字并检查其位数是没有意义的。 You can simply construct numbers with 2 bits and add them up. 您可以简单地用2位构造数字并将其相加。
You can construct a number with 2 bits by picking two different bit positions in the long, the "higher" bit and the "lower" bit": 您可以通过在long中选择两个不同的位位置来构造一个2位数字,即“较高”位和“较低”位”:
long i = (1 << higher) + (1 << lower);
So, you can simply loop over all such numbers, until the value you have constructed exceeds your limit: 因此,您可以简单地循环所有这些数字,直到构造的值超出限制为止:
long sum = 0;
outer: for (int higher = 1; higher < 63; ++higher) {
for (int lower = 0; lower < higher; ++lower) {
long i = (1 << higher) + (1 << lower);
if (i <= n) {
sum += i;
}
if (i >= n) break outer;
}
}
Let's say we know the closest number, x
, equal to or lower than N with 2 set bits, then we can use the formula for power series to quickly sum all positions of the two set bits, for example, if x = b11000
, we sum 假设我们知道最接近的数x
等于或小于N,带有2个置位,那么我们可以使用幂级数公式快速求和两个置位的所有位置,例如,如果x = b11000
,我们和
4*2^0 + S(4)
+ 3*2^1 + S(4) - S(1)
+ 2*2^2 + S(4) - S(2)
+ x
where S(n) = 2 * (1 - 2^n) / (1 - 2)
= 2 + 2^2 + 2^3 ... + 2^n
With numbers encoded 2 out of 5 , exactly two bits are set in every one-digit number. 使用5中的2编码的数字时,每个一位数字中恰好设置了两位。 The sum is 45, with the exception of N×(N-1)/2
for 0≤ N
<9. 的总和是45,与外N×(N-1)/2
为0≤ N
<9。
I think the question is supposed to discover the pattern. 我认为这个问题应该可以找到模式。
Fast forward. 快进。 Given a number N, you can tell the largest number should count by bitmask from the first two bits are set. 给定数字N,您可以知道应该从设置的前两位开始按位掩码计数最大的数字。 So you have a smaller number M 所以你有一个较小的M
Skip to next counted number Given any number with two bit set, next largest number is the shift the second bit by one, until underflow. 跳到下一个计数的数字给定设置了两位的任何数字,下一个最大数字是将第二个位移位一位,直到下溢。
Skip to next order When underflow happens on set two, shift the highest bit by one and also the bit on it's right. 跳到下一个顺序当第2组发生下溢时,将最高位移1,也将其右移。
You don't really need a loop on N, but the bits it have. 您实际上并不需要在N上循环,但需要循环。
Next question: can you answer a large number? 下一个问题:您能回答很多吗? which N >100,000,000 N> 100,000,000
Next Next question: can you answer the same question for X bits when X>2 下一个下一个问题:当X> 2时,您能否针对X位回答相同的问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.