"Go" an array of three digits A, B, C appears only once, and the other numbers appear two times. Please find three numbers that appear only once.

Source: Internet
Author: User

Transferred from: http://zhedahht.blog.163.com/

Title: Three digits A, B, c appear only once in an array, and the other numbers appear two times. Please find three numbers that appear only once.

Analysis: In the blog http://zhedahht.blog.163.com/blog/static/2541117420071128950682/we discussed how to find two occurrences of a number in an array. In this problem, if we can find a number that only appears once, the remaining two numbers that appear only once are easy to find out.

If we make all the numbers in the array different or up, the final result (recorded as x) is the XOR result (x=a^b^c) of A, B, and C three numbers. Other numbers that have occurred two times have been offset from each other in the XOR operation.

We can prove that an XOR result x cannot be any of a, B, c three distinct numbers. We use contradiction to prove it. Suppose x equals one of a, B, C. For example, x equals A, i.e. a=a^b^c. So b^c equals 0, that is, B equals C. This contradicts A, B, and C are three different three numbers.

Because X and a, B, c are different, so x^a, X^b, x^c are not equal to 0.

We define a function f (n), which results in preserving the last 1 in the binary representation of the number N and turning all the other bits into 0. For example, decimal 6 means that binary is 0110, so the result of F (6) is 2 (binary 0010). The results of F (x^a), F (x^b), F (x^c) are not equal to 0.

We then consider the results of F (x^a) ^f (x^b) ^f (x^c). Since only one digit in the binary representation of the result of a n,f (n) of non-0 is 1, the result of F (x^a) ^f (x^b) ^f (x^c) is certainly not 0. This is because the result for any three nonzero number I, J, K,f (i) ^f (j) is either 0, or the result has two 1 in the binary result. In either case, F (i) ^f (j) cannot be equal to f (k), since F (k) is not equal to 0, and only one of the binary results is 1.

So at least one of the binary results of F (x^a) ^f (x^b) ^f (x^c) is 1. Assume that the last digit is 1 bits. Then the results of X^a, X^b, X^c, and one or three digits of the first m bit are 1.

Next we prove that the three results of X^a, X^b and X^c are unlikely to be 1 m bits. or prove it with contradiction. If the X^a, X^b, and X^c are all 1, then the M-bits of a, B, c three digits and the M-bits of x are the opposite, so that the first and second digits of a, B, and C three are the same. If the bit m of a, B, and C three digits are the 0,x=a^b^c result, the first m bit is 0. Since the first m bits of the x and a two digits are the 0,x^a results, the first m bit should be 0. The same can be proved that x^b, x^c the first m bit is 0. This contradicts our assumptions. If the bit m of a, B, and C three digits are the 1,x=a^b^c result, the first m bit is 1. Since the first m bits of the x and a two digits are the 1,x^a results, the first m bit should be 0. The same can be proved that x^b, x^c the first m bit is 0. This is still in contradiction with our assumptions.

So X^a, X^b, x^c three numbers, only one digit of the first m bit is 1. So we found a standard that distinguishes between a, B, and C three numbers. Of these three numbers, only one number satisfies this standard, while the other two numbers are not satisfied. Once this meets the standard figure, the other two numbers can be found.

The C + + code for this idea is as follows:

void Getthreeunique (vector<int>& numbers, vector<int>& unique)

{

if (Numbers.size () < 3)

Return

int xorresult = 0;

Vector<int>::iterator iter = Numbers.begin ();

for (; ITER! = Numbers.end (); ++iter)

Xorresult ^= *iter;

int flags = 0;

for (iter = Numbers.begin (); ITER! = Numbers.end (); ++iter)

Flags ^= lastBitOf1 (xorresult ^ *iter);

Flags = LASTBITOF1 (flags);

Get the first unique number

int first = 0;

for (iter = Numbers.begin (); ITER! = Numbers.end (); ++iter)

{

if (lastBitOf1 (*iter ^ xorresult) = = flags)

First ^= *iter;

}

Unique.push_back (first);

Move the first unique number to the end of array

for (iter = Numbers.begin (); ITER! = Numbers.end (); ++iter)

{

if (*iter = = first)

{

Swap (*iter, * (Numbers.end ()-1));

Break

}

}

Get the second and third unique numbers

Gettwounique (Numbers.begin (), Numbers.end ()-1, unique);

}

int lastBitOf1 (int number)

{

Return number & ~ (NUMBER-1);

}

void Gettwounique (Vector<int>::iterator begin, Vector<int>::iterator end, vector<int>& unique)

{

int xorresult = 0;

for (vector<int>::iterator iter = begin; iter = end; ++iter)

Xorresult ^= *iter;

int diff = lastBitOf1 (xorresult);

int first = 0;

int second = 0;

for (vector<int>::iterator iter = begin; iter = end; ++iter)

{

If (diff & *iter)

First ^= *iter;

Else

Second ^= *iter;

}

Unique.push_back (first);

Unique.push_back (second);

}

In the above, Getthreeunique finds three occurrences of a number from an array, and Gettwounique finds two occurrences of a number only once from the array. LASTBITOF1 implements the function f (n) in the analysis, which retains only the last 1 of the binary representation of the number n, and all the other bits into 0.

In the function Getthreeunique, we save the result of a, B, c three number XOR to Xorresult in the first for loop, and then we find F (x^a) ^f (x^b) ^f (x^c) in the second for loop and save it in the variable flags. In the statement flags=lastbitof1 (flags), the last digit in the binary of the F (x^a) ^f (x^b) ^f (x^c) result is 1 bits. And according to this digit, we find the first one that appears only once. The first is then swapped to the end of the array, and two other occurrences of the number are found in the previous n-1 number of the array.

"Go" an array of three digits A, B, C appears only once, and the other numbers appear two times. Please find three numbers that appear only once.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.