zoukankan      html  css  js  c++  java
  • 位运算经典例题

    异或实现加法

    int add(int a, int b){
        return a & b == 0 ? a ^ b : add(a ^ b,  (a & b) << 1);
    }
    

    Single Number

    问题描述:数组中有一个元素出现了p次,其他元素均出现了k次,求该元素
    解决方法:
    正常思路是统计每个元素出现的次数,即可求出该元素,通过位运算,我们可以实现对元素的统计
    先令p = p % k,这样我们统计的上限最多为k,需要(m = log left lceil k ight ceil)个位来表示,也就是对每个位进行计数。

    我们先单单看一位,比如32位整数的第一位1st,对于新来的数,如果新来的数该位为1,则我们需要增加第一位对应的m-counter计数器,当计数器达到k时清空为0,最后的p的二进制表示对应的x即可。
    先用一个例子说明一下,如k=5,p=3那么对于32位整数的第一位而言,如果single number的该位为1的话,那么该位对应的计数器必定计数了k * r(r为整数) + p次,由于p=3(二进制11)那么该计数器的第一位和第二位都会被置为1,其他位同理,返回x1或者x2即可
    现在的主要问题就为当一个位上的1或0来的时候

    • 如何在计数器上实现加法
    • 如何在计数器计数达到k时清零
      对于第一个问题,我们知道只有当前m-1个数全是1的时候,遇到0才会进位,
        xm ^= (xm-1 & xm-2 & .. & i)
        xm-1 ^=  ( xm-2 & .. & i)
        x1 ^= i
    

    对于第二个问题,我们可以用掩码解决,假定k的二进制表示为101,那么只要第3位和第1位为1,说明计数器已满,需要清0

        mask = ~ (x1 & ~x2 & x3)
        x1 &= mask
        xm &= mask
    

    例题

    137. Single Number II
    k=3, p = 1

    class Solution {
    public:
        int singleNumber(vector<int>& nums) {
            int x2 = 0, x1 = 0, mask;
            for(int i : nums){
                x2 ^= (x1 & i);
                x1 ^= i;
                mask = ~(x1 & x2);
                x1 &= mask;
                x2 &= mask;
            }
            
            return x1;
        }
    };
    

    另一种思路也可以使用01来实现三进制,根据真值表写出逻辑表达式

    class Solution {
    public:
        int singleNumber(vector<int>& nums) {
            int a = 0, b = 0;
            for(int i = 0; i < nums.size(); i++){
                
                int t = (~a&b&nums[i]) | (a&~b&~nums[i]);
                b = (~a&b&~nums[i]) | (~a&~b&nums[i]);
                a = t;
                
            }
            
            return a | b;
        }
    };
    

    参考

  • 相关阅读:
    Linux 搭建SVN server
    GREENPLUM简单介绍
    监听手机录音
    Java NIO与IO的差别和比較
    元数据驱动思考实例分析
    jQuery推断复选框是否勾选
    BitBlt介绍
    Android灭亡论之Firefox OS操作系统出现
    CEGUI添加自定义控件
    IFrame和Ajax比較
  • 原文地址:https://www.cnblogs.com/qbits/p/11369631.html
Copyright © 2011-2022 走看看