Find three numbers appeared only once

后端 未结 6 1983
说谎
说谎 2020-12-08 03:15

In a sequence of length n, where n=2k+3, that is there are k unique numbers appeared twice and three numbers appeared only once.

The question is: how to fin

6条回答
  •  不知归路
    2020-12-08 04:02

    This is a classic question - I was actually just asked it a few weeks ago. To solve it, you take the number of possible distinct numbers that could appear, and allocate that many bits.

    For example, if numbers in the list must be between 1-20, you allocate 20 bits - one for each number, and you initialize each bit as 0.

    Then you traverse the list. Every time you see a number, flip the corresponding bit.

    For example: With your example list of 2 6 3 6 5 7 7, we could allocate 7 bits (for 1 2 3 4 5 6 7). Then as we traverse the list, we would do the following:

    • flip 2nd bit
    • flip 6th bit
    • flip 3rd bit
    • flip 6th bit
    • etc

    Then once you're done traversing the list, you can read through the bits to find the three unique numbers. They will all be represented by '1' bits, and the other numbers will be represented by 0s.

    You read through the list twice, which takes 2n time, which is O(n).


    Edit: It is possible that the bounds will not be given. One solution, then, is to simply read through the list first to determine the bounds yourself - then it's still O(n).

    However one problem which could occur is that the list could be very small, but some very large numbers - effectively making the range too big. For example:

    1, 99999999999999999, 1, 99999999999999999, 2, 3, 4
    

    Solving that problem would require a lot of memory due to the large number present in the list, because even though there are very few numbers, the range is very large and we are allocating bits according to the range.

    The solution could then be adjusted to give a new solution as follows using a hashtable (although I'm not sure if this is permitted given the problem's "bit manipulation only" stipulation):

    1. Let L denote the original list, and C denote a copy of it.
    2. Remove all duplicates from C (there are numerous ways of doing this efficiently).
    3. Create a hashtable H, and for each element in C, insert a key/value pair <number,pos> into H where number is the current element in C, and pos is its position in C. So, given a number that appears in L, we can now use H to find that number's position in C.
    4. Allocate a number of bits equal to the size of C, and initialize those bits to 0.
    5. Traverse L. Each time we run accross a number, get its value from H, and flip that bit in our bit list.
    6. Traverse the bit list - for each '1' bit, get the number from C which is at that position - that is one of the unique numbers.

提交回复
热议问题