leetcode-位运算

吃可爱长大的小学妹 提交于 2020-01-25 03:41:09

位运算

LeetCode 231. Power of Two

class Solution {
public:
    bool isPowerOfTwo(int n) {
        return n>0 && (1 << 30)%n == 0;
        //return (n>0 && (n & -n) == n);
    }
};
//lowbit,取出n二进制中第一个1的位置k
/*
lowbit(n) = n & ( ~ n + 1 ) 
又在补码中,~n+1= - n,所以
lowbit(n) = n & (- n)
那lowbit有什么应用呢?我们可以求得一个数字二进制中所有1的个数,从而得到0的个数……
https://www.cnblogs.com/CuteAbacus/p/9464358.html
*/

LeetCode 762. Prime Number of Set Bits in Binary Representation

class Solution {
public:
    int countPrimeSetBits(int L, int R) {
        unordered_set<int> primes({2,3,5,7,11,13,17,19});
        int res = 0;
        for(int i = L; i <= R; i++)
        {
            int s = 0;
            int k = i;
            while(k)
            {
                s += k & 1;
                k >>= 1;
            }
            if(primes.count(s))
                res++;
        }
        return res;
    }
};
//判断1的个数

LeetCode 136. Single Number

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        if(nums.size() == 0)return 0;
        int res = nums[0];
        for(int i = 1; i < nums.size(); i++)
        {
            res ^= nums[i];
        }
        return res;
    }
};
//异或的性质,但是如果留下两个呢?

LeetCode 476. Number Complement

class Solution {
public:
    int findComplement(int num) {
        int res = 0;
        int t = 0;
        while(num)
        {
            res += (!(num & 1)) << t;
            num >>= 1;
            t++;
        }
        return res;
    }
};
//取1

LeetCode 137. Single Number II

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        //方法一:
        // int ans = 0;
        // for(int i = 0; i < 32; i++)
        // {
        //     int count = 0;
        //     for(int j = 0; j < nums.size(); j++)
        //     {
        //         count += nums[j] >> i & 1;
        //     }
        //     ans += (count%3) << i;
        // }
        // return ans;
        //神仙做法:
        //状态机,初始为0,0
        //1个1, 1 0; 2个1, 0 1; 3个1, 0 0
        int ones = 0, twos = 0;
        for(auto x : nums)
        {
            ones = (ones ^ x) & ~twos;
            twos = (twos ^ x) & ~ones;
        }
        return ones;
    }
};

LeetCode 260. Single Number III

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        //得到两个数异或的结果
        int s = 0;
        for(auto x : nums) s ^= x;

        //找到第k位,是不是可以用lowbit
        int k = 0;

        while(!(s >> k & 1))k++;

        //分组异或
        int s2 = 0;
        for(auto x : nums)
        {
            if(x >> k & 1)
                s2 ^= x;
        }
        int s3 = s ^ s2;
        return vector<int>({s2, s3});
    }
};
//这里用到了取最低位

LeetCode 371. Sum of Two Integers

class Solution {
public:
    int getSum(int a, int b) {
        if(!b)return a;
        int sum = a ^ b;
        unsigned int carry = (unsigned int)(a & b) << 1;
        return getSum(sum, carry);
    }
};
//carry要是无符号整形,对负数有效

LeetCode 201. Bitwise AND of Numbers Range

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;
    }
};
//这题没看懂

LeetCode 477. Total Hamming Distance

class Solution {
public:
    int totalHammingDistance(vector<int>& nums) {
        int res = 0;
        for(int i = 0; i <= 30; i++)
        {
            int ones = 0;
            for(auto x : nums)
            {
                if(x >> i & 1)
                    ones++;
            }
            res += ones * (nums.size() - ones);
        }
        return res;
    }
};
//这题关键是巧妙的汉明距离,变成了某一个1个个数和0的个数的乘积

LeetCode 421. Maximum XOR of Two Numbers in an Array

class Solution {
public:

    struct Node
    {
        int son[2];
    };

    vector<Node> nodes; 

    int findMaximumXOR(vector<int>& nums) {
        nodes.push_back(Node({0,0}));

        for(auto x : nums)
        {
            int p = 0;
            for(int i = 30; i >= 0; i--)
            {
                int t = x >> i & 1;
                if(!nodes[p].son[t])
                {
                    nodes.push_back(Node{0,0});
                    nodes[p].son[t] = nodes.size() - 1;
                }
                p = nodes[p].son[t];
            }
        }

        int res = 0;
        for(auto x : nums)
        {
            int p = 0, XOR = 0;
            for(int i = 30; i >= 0; i--)
            {
                int t = x >> i & 1;
                if(nodes[p].son[!t])
                {
                    p = nodes[p].son[!t];
                    XOR += 1 << i;
                }
                else
                {
                    p = nodes[p].son[t];
                }
            }
            res = max(res, XOR);
        }
        return res;    
    }
};
//关键建立一个trie树,然后从最高位开始找不同
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!