Given an array, find the smallest number not in the array

Source: Internet
Author: User

This is an example provided by Liu Xinyu in the Tl discussion. I think the idea is quite enlightening. So I should record it.

Given an array, its content is random, non-repeating positive integers, such:

{4, 23, 1, 8, 9, 21, 6, 12}

It is required to find the smallest number that does not appear in the array. For example, the minimum value that does not appear in the array is: 2.

The actual application prototype of this problem can be an ID distribution system, which uses an array to save the allocated ID. Each time it is recycled, an element (O (N) is deleted from the array )), for allocation, you need to find the smallest available ID.AlgorithmWhat to do.

The transformation from the naive solution to the quick solution is very clever. Of course, if you have never touched a similar question before, it should not be easy to notice this feature.

Set the array to A, the size is N, and the subscript starts from 1. Below is a series of improved algorithms:

I. Search for resources

General problems can be solved in this very violent way, from 1 to n to determine whether it is in the array one by one:

MIN-AVAILABLE-NUM (A, n)

For I = 1 to n

Do if I not in

Then return I

Return n + 1

Obviously, the algorithm complexity here is O (n ^ 2)

2. sort and search by second

The first method is linear search. The first thing to improve is binary search. The premise of binary search is order:

    1. Sort first, and use the fast sorting of O (nlgn), Merge Sorting, or heap sorting. Because the elements in the array are some natural numbers, we can even use the base sorting of O (N). Of course, more memory is required.
    2. 1. N is determined, and the complexity is O (nlgn)

Therefore, the overall algorithm complexity is O (nlgn)

3. A feature of the array

In fact, if you carefully observe the array a [1]... A [n], we can draw a conclusion: if there is an unused number in the array, then max (a)> N.

The proof is very simple. Suppose max (a) <= n. Because the array size is N, the elements in the array can only be an arrangement from 1 to n, so that there is no unused number in the array.

This feature is similar to the drawer principle.

So we can have another method:

    1. Sort first
    2. Search by using this feature

MIN-AVAILABLE-NUM (A, n)

For I = 1 to n

Do a [I]> I

Then return I

Return n + 1

 

Note that if we use base sorting, we can reduce the complexity to O (n ).

4. A linear time and linear space Algorithm

Although the third algorithm can reach O (n) in the theoretical sense, the constant factor hidden in the base sorting is large, and it is not in-situ sorting. Here we provide an algorithm that does not need to be sorted:

MIN-AVAILABLE-NUM (A, n)

For I = 1 to n

B [I] = 0

For I = 1 to n

Do if a [I] <n

Then B [A [I] = 1

For I = 1 to n

If (B [I] = 0) return I;

Return n + 1;

Here, an auxiliary array B is used to indicate whether the numbers 1 to n exist in array A. If they do not exist, the number is marked as 0, finally, the first value 0 in B is the element we are looking for. If all the elements in B are 1, it means that a uses all the numbers from 1 to n, the return value is the next n + 1.

No sorting is required here, And the complexity is O (n), but an additional array of O (n) is required.

5. An Algorithm for Linear Time and constant Space

With the principle of fast sorting, we can achieve O (n) efficiency without using additional arrays. The principle is:

Take the median M = (1 + N)/2 from 1 to n and use M to divide the array into A1 and A2. All elements in A1 are less than or equal to M, all the elements in A2 are larger than m (note that the subscript is used here, instead of a [m]). If the A1 size is m, the idle element is in A2, this is proved before, and then the same method is applied in A2.

MIN-AVAILABLE-NUM (A, low, up)

If (Low = up) return low

M = (low + up)/2

Split = partition (A, low, up, m)

If a [split] = m

Then return MIN-AVAILABLE-NUM (A, low, split)

Else return MIN-AVAILABLE-NUM (A, split + 1, up)

Here the recursion formula is T (n) = T (n/2) + O (N). According to the third case of the main theorem, the complexity is O (n ), in fact, it is an equiratio series: N + n/2 + N/4...

However, because recursion is used here, the space complexity is actually O (lgn), so it can be replaced by loops:

MIN-AVAILABLE-NUM (A, low, up)
While low! = Up
M = (low + up)/2
Split = partition (low, up, m)
If a [split] = m
Then low = split + 1
Else up = Split-1
Return low

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.