我有一个问题,我必须添加从1到N的数字,其设置位为2.对于N = 5,我们应该得到值8,因为数字3和5有2位设置为1。我在java中实现了相同的功能。我得到的o / p对于int值是正确的,但是当涉及到长值时,要么花费大量时间或冻结,当我在代码判断网站上提交相同内容时,它就是给运行时间超出消息。请指导我如何优化我的代码以更快地运行它,谢谢:)
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));
}
答案 0 :(得分:1)
正如@hbejgel指出的那样,循环所有数字并检查其位数是没有意义的。您可以简单地构造2位数字并将它们相加。
你可以通过在long中选择两个不同的位位置来构造一个2位的数字,&#34;更高的&#34; bit和&#34; lower&#34;位&#34;:
long i = (1 << higher) + (1 << lower);
因此,您可以简单地遍历所有这些数字,直到您构建的值超出限制:
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;
}
}
答案 1 :(得分:0)
假设我们知道最接近的数字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
答案 2 :(得分:0)
对于编号为2 out of 5的数字,每个一位数字中都设置了两位。总和为45,但N×(N-1)/2
除外,0≤N
<9。
答案 3 :(得分:0)
我认为问题应该是发现模式。
快进。给定数字N,您可以说出最大的数字 应该从前两位的位掩码计数。所以你有了 较小的数字M
跳到下一个计数的数字给定任意两位设置的数字,下一个 最大的数字是第二个位移一个,直到下溢。
跳到下一个顺序当第二组发生下溢时,移动 一点一点,也就是右边的一点。
你真的不需要N上的循环,但它有它的位。
下一个问题:你能回答多少?其中N> 100,000,000
下一个下一个问题:当X> 2
时,你能回答X位的相同问题吗?