位运算专题

2 篇文章 0 订阅

超级无敌蒟蒻重新和y总学习.jpg

链接
231. 2的幂

Given an integer, write a function to determine if it is a power of two.

Example 1:

Input: 1
Output: true 
Explanation: 20 = 1

两种方法,一种利用int表示的最大2的幂2^30去%这个数,得0就是2的幂

第二种利用补码性质n&(-n)表示二进制表示中中最右边的一,如果和n相同则是2的幂

return n > 0 && (1<<30) % n == 0;
return n > 0 && (n & -n) == n;

762. Prime Number of Set Bits in Binary Representation

198287Add to ListShare

Given two integers L 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 10101 which 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 is prime)
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:

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

数据最大为106小于220,所以只有前20位可能为0,则暴力枚举即可

class Solution {
public:
    int countPrimeSetBits(int L, int R) {
        unordered_set<int> prime({2,3,5,7,11,13,17,19});
        int res = 0;
        for(int i = L; i <= R; ++i)
        {
            int time = 0;
            for(int k = i; k; k >>= 1)
                time += k & 1;
            if (prime.count(time))
                ++res;
        }
        return res;
    }
};

476. Number Complement

Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.

Note:

  1. The given integer is guaranteed to fit within the range of a 32-bit signed integer.
  2. You could assume no leading zero bit in the integer’s binary representation.

Example 1:

Input: 5
Output: 2
Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.

Example 2:

Input: 1
Output: 0
Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.

直接把每位反转即可,注意在 反转每位时不能用~ ,因为其会将前导0一起反转,所以要用非!

class Solution {
public:
    int findComplement(int num) {
        int res = 0, t = 0;//结果,当前第几位
        while(num)
        {
            res += !(num & 1) << t; //注意!这里
            num >>= 1++t;
        }
        return res;
    }
};

136. Single Number

Given a non-empty array of integers, every element appears twice except for one. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

Input: [2,2,1]
Output: 1

Example 2:

Input: [4,1,2,1,2]
Output: 4

利用两个相同的数异或和为0的性质

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res = 0;
        for(auto x:nums)
            res ^= x;
        return res;
    }
};

137. Single Number II

Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

Input: [2,2,3,2]
Output: 3

Example 2:

Input: [0,1,0,1,0,1,99]
Output: 99

因为除了一个数外所有的数都出现三次,所以在二进制的每一位中1的个数总是3的倍数或者3倍数+1,所以当3+1时就证明是出现一次数字的位数,将其加进答案位数就行,注意有负数要统计全部的31位

是一个纵向统计的过程

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res = 0;
        for(int bit = 0;bit < 32; ++bit)//枚举所有位
        {
            int time = 0;
            for(auto x:nums)
                time += (x>>bit) & 1;
            res += (time % 3) << bit; 
        }
        return res;
    }
};

260. Single Number III

Medium

117690Add to ListShare

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

Example:

Input:  [1,2,1,3,2,5]
Output: [3,5]

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

和一方法类似,首先计算所有数的异或和。因为有两个不一样的数所以异或和中必有一位不唯一,所以将这位1作为一个标准将所有的数非为这位为1和不为一的两堆,再计算异或和即可

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int s = 0;
        for(auto x:nums) s ^= x;
        int pos = 0;
        while(!(s>>pos & 1)) ++pos;
        int s2 = 0;
        for(auto x:nums)
            if(x>>pos & 1)
                s2 ^= x;
        return vector<int> ({s2,s^s2});
    }
};

371. Sum of Two Integers

Easy

10321905Add to ListShare

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.

Example 1:

Input: a = 1, b = 2
Output: 3

Example 2:

Input: a = -2, b = 3
Output: 1

加法可以用亦或和与运算来代替,亦或是不进位加法,与运算左移一位得到的就是进位,当左移次数最多31次后就为0,也就是递归结束条件,0加任何数就是数本身

class Solution {
public:
    int getSum(int a, int b) {
        if(!b) return a;
        int sum = a ^ b,carry = uint(a & b) << 1;//转换成unsigned int,否则有的负数会越界
        return getSum(sum,carry);
    }
};

201. Bitwise AND of Numbers Range

Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.

Example 1:

Input: [5,7]
Output: 4

Example 2:

Input: [0,1]
Output: 0

与运算有一个0就肯定得0,所以从最小的m开始考虑,只有m得1的位k才有可能是1,对于大于m的数需要考虑第k位是否为0。

则只需判断第一个k位为0的数是否在[m,n]中出现即可

        k 分析第二个出现的1
m = 1010101
    1011000 k位为0的最小的数,则只需得出这个数就行
-----------
m = 1010101
	0000100 拥有k这个位的1,1 << k实现
	0000011 减1
	1111100 取反
 &m 1010101
  = 1010100
    1011000 加 1 << k,得出所需数

上面的操作是位运算很重要的一些转移数的操作

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int res = 0;
        for(int i = 0; (1LL << i) <= m; ++i)
            if(m >> i & 1)
            {
                if((m & ~((1 << i) - 1LL)) + (1 << i) > n) 
                    res += 1 << i;
            }
        return res;
    }
};

477. Total Hamming Distance

The Hamming distancebetween two integers is the number of positions at which the corresponding bits are different.

Now your job is to find the total Hamming distance between all pairs of the given numbers.

Example:

Input: 4, 14, 2

Output: 6

Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just
showing the four bits relevant in this case). So the answer will be:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.

Note:

  1. Elements of the given array are in the range of 0to 10^9
  2. Length of the array will not exceed 10^4.

汉明距离就是两个数二进制表示中,相同位如果不同则加一.所以对于不同的数来说每位都是独立的,纵向考虑即可

1
0
1
0 
这4个数的汉明距离是4,也是1个数和0个数的乘积也就是c21*c21,从两个1中选一个再从两个0中选一个
class Solution {
public:
    int totalHammingDistance(vector<int>& nums) {
        int res = 0;
        for(int bit = 0; bit < 31; ++bit)
        {
            int ones = 0;
            for(auto x : nums)
                if(x >> bit & 1)
                    ++ones;
            res += ones * (nums.size() - ones) ;
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值