Leetcode刷题笔记(C++)——位运算

Leetcode刷题笔记(C++)——位运算

整理一下刷题过程中的思路,在这里进行一下总结与分享。
github地址:https://github.com/lvjian0706/Leetcode-solutions
github项目是刚刚新建的,陆续会将整理的代码以及思路上传上去,代码是基于C++与python的。同时会将基础的排序算法等也一并进行整理上传。

136. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4

class Solution {
    
    
public:
    /*
    由于时间和空间限制,所以使用二进制的异或运算解答即可;
    */
    int singleNumber(vector<int>& nums) {
    
    
        int ans = nums[0];
        for(int i=1; i<nums.size(); i++){
    
    
            ans ^= nums[i];
        }
        return ans;
    }
};

191. 位1的个数

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。
示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。
示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。

方法1class Solution {
    
    
public:
    /*
    返回二进制表达式中数字位数为 ‘1’ 的个数:
    求二进制数(对2取余后整除2),当该位为1时,ans++;
    */
    int hammingWeight(uint32_t n) {
    
    
        int ans = 0;
        while(n!=0){
    
    
            ans += (n % 2);
            n /= 2;
        }
        return ans;
    }
};

方法2class Solution {
    
    
public:
    /*
    返回二进制表达式中数字位数为 ‘1’ 的个数:
    n = n & (n-1) : 将最后一个1置0;
    将最后一个1循环置0,直到所有位上都是0;
    */
    int hammingWeight(uint32_t n) {
    
    
        int ans = 0;
        while(n){
    
    
            n = n & (n-1);
            ans++;
        }
        return ans;
    }
};

260. 只出现一次的数字 III

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。

示例 :
输入: [1,2,1,3,2,5]
输出: [3,5]

class Solution {
    
    
public:
    /*
    找出只出现一次的那两个元素:因为是常数空间,考虑位运算:
    x & (-x) :保留位中最右边1,且将其余的1设为0。 
    1. xy ^= nums[i]:先找到只出现过一次的两个数的异或结果;
    2. dif = xy & (-xy):找出x与y不同的一位(最右边一位);
    3. x ^= nums[i]:找到x;
    4. xy^x:找到y;
    */
    vector<int> singleNumber(vector<int>& nums) {
    
    
        vector<int> ans;
        int xy=0;
        for(int i=0; i<nums.size(); i++){
    
    
            xy ^= nums[i];
        }
        int dif = xy & (-xy);
        int x = 0;
        for(int i=0; i<nums.size(); i++){
    
    
            if(nums[i]&dif){
    
    
                x ^= nums[i];
            }
        }
        ans.push_back(x);
        ans.push_back(xy^x);
        return ans;
    }
};

338. 比特位计数

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]

class Solution {
    
    
public:
    /*
    对于0≤i≤num范围中的每个数字i,计算其二进制数中的1的数目并将它们作为数组返回:动态规划问题
    1. 奇数:二进制表示中,奇数一定比前面那个偶数多一个 1,因为多的就是最低位的 1。
    2. 偶数:二进制表示中,偶数中 1 的个数一定和除以 2 之后的那个数一样多。因为最低位是 0,除以 2 就是右移一位,也就是把那个 0 抹掉而已,所以 1 的个数是不变的。
    */
    vector<int> countBits(int num) {
    
    
        vector<int> dp(num+1);
        dp[0] = 0;
        for(int i=1; i<num+1; i++){
    
    
            if(i%2==0){
    
    
                dp[i] = dp[i/2];
            }
            else{
    
    
                dp[i] = dp[i-1] + 1;
            }
        }
        return dp;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43273742/article/details/107740748
今日推荐