762. Prime Number of Set Bits in Binary Representation(python+cpp)

题目:

Given two integersL and R, find the count of numbers in the range [L,R] (inclusive) having a prime number of set bits in their binary representation. (Recall that the number of set bits an integer has is the number of 1s present when written in binary. For example, 21 written in binary is 10101which has 3 set bits. Also, 1 is not a prime.)
Example 1:

Input: L = 6, R = 10 
Output: 4 
Explanation: 
6 -> 110 (2 set bits, 2 isprime) 
7 -> 111 (3 set bits, 3 is prime) 
9 -> 1001 (2 set bits , 2 is prime) 
10->1010 (2 set bits , 2 is prime) 

Example 2:

Input: L = 10, R = 15 
Output: 5 
Explanation: 
10 -> 1010 (2 set bits, 2 is prime) 
11 -> 1011 (3 set bits, 3 is prime) 
12 -> 1100 (2 set bits,2 is prime) 
13 -> 1101 (3 set bits, 3 is prime) 
14 -> 1110 (3 set bits, 3 is prime) 
15 -> 1111 (4 set bits, 4 is not prime) 

Note:
L, R will be integers L <= R in the range [1, 10^6]. R - L will be at most 10000.

解释:
求给定范围[L,R]内,二进制表达中1的个数是素数的个数有多少个。
1.素数的判断,由于数字最大是106所以可以用20位的二进制表达数字,那么可以用一个长度为20的数组储存该数字是否是素数。可以用动态规划来解。
是否是素数还是不要用传统的开根号法则判断了,速度太慢。
传统开根号法:

def isPrime(num):
	if num<=1:
	    return False
	for i in range(2,int(num**0.5)+1):
	    if num%i==0:
	        return False
	return True

动态规划法:

N=20
isPrime=[True]*N
isPrime[0]=False
isPrime[1]=False
for i in range(2,N):
    if isPrime[i]:
        for j in range(i*i,N,i):
            isPrime[j]=False

2.求一个数的二进制表达中1的个数,有个技巧。(当然,python的话可以直接count)
假如x是一个二进数,例如x=0xfffa(1111 1111 1111 1010),要实现去掉最低位一个1,可进行的操作是x&=(x-1),此时x==0xfff8(1111 1111 1111 1000) 。基于该思想,利用wile循环对(x)判断,可实现计算二进制数中所有位上1的个数。

int numOfOne(x){
int count = 0;
while(x)
    {
    count++;
    x = x&(x-1); 
     }
return count;
}

3.求一个数的二进制表达中0的个数
假如x是一个二进数,例如x=0xfffa(1111 1111 1111 1010),要实现去掉最低位一个0,可进行的操作是x|=(x+1),此时x==0xfffb(1111 1111 1111 1011) ;再去掉一个0,同样,x|=(x+1),则x==0xffff。如果x的2字节表示,则(x+1)为0。基于该思想,利用wile循环对(x+1)判断,可实现计算二进制数中所有位上0的个数。注意,x=1时,1的高位默认有0的(注意是所有位而不是写出来的位上,因为二进制高位的0是默认不写出来的,但是不写出来不代表没有啊)。

int Grial(int x)
{
    int count = 0;
    while (x + 1)
    {
        count++;
        x |= (x + 1);
    }
    return count;
}

python代码:

class Solution:
    def countPrimeSetBits(self, L, R):
        """
        :type L: int
        :type R: int
        :rtype: int
        """
        N=20
        isPrime=[True]*N
        isPrime[0]=False
        isPrime[1]=False
        for i in range(2,N):
            if isPrime[i]:
                for j in range(i*i,N,i):
                    isPrime[j]=False
        result=0
        for num in range(L,R+1):
            count=bin(num).count('1')
            if isPrime[count]:
                result+=1
        return result        

c++代码:

#define N 20
class Solution {
public:
    int countPrimeSetBits(int L, int R) {
        vector<bool>isPrime(N,true);
        isPrime[0]=false;
        isPrime[1]=false;
        for(int i=2;i<N;i++)
        {
            if (isPrime[i])
            {
                for (int j=i*i;j<N;j+=i)
                    isPrime[j]=false;
            }
        }
        int result=0;
        for (int i=L;i<=R;i++)
        {
            int count_1=0;
            int n=i;
            while(n)
            {
                count_1+=1;
                n&=(n-1);
            }
            if (isPrime[count_1])
                result+=1;
        }
        return result;  
    }
};

总结:
判断一个数是否是素数的快速求法和求数字的二进制表达中1的个数的技巧。
python的count(‘1’)比手动计算1的个数要快很多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值