XOR in binary and bit operations

1. Give a question: Give you an array of integers. Except for a number that appears only once in this array, other numbers only appear twice. What is the number that appears only once?

Requirements: The time complexity is O (n) and the space complexity is O (1).


The difficulty of this subject is the limitation of space complexity.


Solution: Two numbers appear in one number, two numbers are the same, and the XOR value of two equal numbers is 0, so we only need to XOR the number of the entire array, we can get the one that appears only once digital


<span style="font-size:18px;">int get_one_num(int num[] , int n)
{
    int first = num[0] , i;
    for(i = 1; i < n; i++)
        first ^= num[i];
    return first;
}</span>


2. Problem two: Now, there are two numbers in this array that appear only once. Find these two numbers, and the time and space complexity remain unchanged.


According to the solution to the first problem, we also get a value at the end, but this value is the XOR value of those two numbers (which only appear once). We don't know either of these two numbers, so we can't get these two numbers.


If we divide the array into two arrays, each array contains only a number that appears only once, and then call the solution of problem 1, we can get the result.

The key is how do we split this array, and the space complexity is O (1)?

First of all, we sequentially XOR each number in the array, and the result is two XOR results that only appear once. Because the two numbers must be different, the result number is definitely not 0, which is At least one bit of this binary digital clock is 1, we find the position of the first bit in the resulting digital Chinese, and record it as the nth bit, and we will divide the array into one by whether the nth bit is 1. Array.


Code


<span style="font-size:18px;">int find_one(int x)
{
    int p = 1;
    while(true)
    {
        if((p^x) < x)  break;
        p <<= 1;
    }
    return p;
}

void get_one_num(int num , int n)
{
    int first = num[0] , i;
    for(i = 1; i < n; i++)
        first ^= num[i];
    int one = find_one(first);

    int x = 0 , y = 0;
    for(i = 0; i < n; i++)
    {
        if((one^num[i]) < num[i])
            x ^= num[i];
        else y ^= num[i];
    }

    cout<<(x<y?x:y)<<" "<<(x>y?x:y)<<endl;
}</span>




Published 190 original articles · 19 praises · 200,000+ views

Guess you like

Origin blog.csdn.net/zengchenacmer/article/details/38059317