Bit computing classic example

XOR addition with

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

Single Number

Problem Description: There is a array element appears p times, other elements have emerged k times, this element seek
solutions:
normal idea is to count the number of times each element that appears, you can find the element by bit operation, we statistics can be achieved on the elements of
shillings p = p% k, so our statistical upper limit of a maximum of k, need \ (m = \ log \ left \ lceil k \ right \ rceil \) bits to represent, that is, for every bit counted.

Let's look at just one, such as the first bit of the 1st 32 bit integer for the number of new, if the number of the new bit is 1, then we need to increase the first counter corresponding to the m-counter, when the counter reaches k is 0 when empty, the last corresponding to the binary representation of p to x.
First explain with an example, such as k = 5, p = 3 then the first bit to 32-bit integers, if the bit is a single number is 1, then the corresponding bit of the counter must count k * r ( r is an integer) + p times, since p = 3 (binary 11) then the first and second bits of the counter will be set to 1, the other bits Similarly, x1 or x2 returns to
main problem now is to when a 1 or 0 bit on the

  • How to achieve an addition on the counter
  • How is cleared when the counter counts k
    For the first question, we know only the current number of full time m-1 1 0 encounter will carry,
    xm ^= (xm-1 & xm-2 & .. & i)
    xm-1 ^=  ( xm-2 & .. & i)
    x1 ^= i

For the second question, we can use a mask to solve, assuming the binary representation of k is 101, so long as the No. 3 and 1 to 1, indicating the counter is full, it needs to be cleared

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

example

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;
    }
};

Another idea can also use 01 to achieve ternary , write logical expressions based on truth table

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;
    }
};

reference

Guess you like

Origin www.cnblogs.com/qbits/p/11369631.html