算法复习:位运算

leetcode 191. 位1的个数

维护匹配串 从1开始逐位移动比较

class Solution {
public:
    int hammingWeight(uint32_t n) 
    {     // uint32_t为32位无符号类型数据
        int count=0;
        uint32_t donser=1;
        for(int i=0;i<32;i++)
        {
            if((n&donser)>=1)
                count++;
            donser<<=1;
        }
        return count;
    }
};
leetcode 191

n与n-1取& 

class Solution {
public:
    int hammingWeight(uint32_t n) 
    {     
        int count=0;
        while(n)
        {
            n=n&(n-1);
            count++;
        }
        return count;
    }
};
leetcode 191

调用内置函数 __builtin_popcount(n)

class Solution {
public:
    int hammingWeight(uint32_t n) 
    {     // uint32_t为32位无符号类型数据
        return __builtin_popcount(n);
    }
};

leetcode 面试题65. 不用加减乘除做加法

位运算 分两步,先算不带进位的,再算进位

class Solution {
public:
    int add(int a, int b) {
        while(b!=0)
        {
            int local=a^b;//不进位
            int far=(unsigned int)(a&b)<<1;//算进位 一直有进位就一直循环 c++不支持负值左移
            a=local;
            b=far;
        }l
        return a;
    }
};
leetcode M65

leetcode 136. 只出现一次的数字

按位亦或即可

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int result=nums[0];
        for(int i=1;i<nums.size();i++)
        {
            result^=nums[i];
        }
        return result;
    }
};
View Code

leetcode 137. 只出现一次的数字 II

33位的数组,统计每一个2进制位出现的个数,%3!=0的就是只出现一次的位

class Solution {
public:
    void from_10_to_2(long long x,vector<int>&donser)
    {
        int i=0;
        if(x<0)
        {
            x*=-1;
            donser[32]+=1;
        }
        while(x>0)
        {
            int tmp=x%2;
            donser[i]+=tmp;
            x=x/2;
            i++;
        }
        return;
    }
    int from_2_to_10(vector<int>&donser)
    {
        long long base=1,result=0;
        for(int i=0;i<32;i++)
        {
            if(donser[i]%3!=0)
                result+=base;
            base*=2;
        }
        if(donser[32]%3!=0)
            result*=-1;
        return result;
    }
    int singleNumber(vector<int>& nums) {
        vector<int>donser(33,0);
        for(int i=0;i<nums.size();i++)
        {
            from_10_to_2(nums[i],donser);
        }
        int result=from_2_to_10(donser);
        return result;
    }
};
View Code

leetcode 260. 只出现一次的数字 III

可以二分计算每一个区间的亦或,两个区间都不为0时就是答案

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int result=nums[0];
        for(int i=1;i<nums.size();i++)
        {
            result^=nums[i];
        }
        vector<int>out(2,0);
        int tmp=result,lable=1;
        int first_visit_0=1,first_visit_1=1;
        while((result&1)==0)
        {
            lable=lable<<1;
            result=result>>1;
            //cout<<lable<<" "<<result<<" "<<tmp<<endl;
        }
        
        for(int i=0;i<nums.size();i++)
        {
            //cout<<lable<<" "<<nums[i]<<" "<<(lable&nums[i])<<endl;
            if((lable&nums[i])==0)
            {
                if(first_visit_0==1)
                {
                    first_visit_0=0;
                    out[0]=nums[i];
                }
                else
                    out[0]^=nums[i];
                //cout<<"@:"<<out[0]<<endl;
            }
            else 
            {
                if(first_visit_1==1)
                {
                    first_visit_1=0;
                    out[1]=nums[i];
                }
                else
                    out[1]^=nums[i];

                //cout<<"#:"<<out[1]<<endl;
            }   
        }
        return out;
    }
};
View Code
原文地址:https://www.cnblogs.com/dzzy/p/12297911.html