For the original question, see the blog of morbet, which refers to a series consisting of 1-1001, add a number between 1-, and then disrupt the order of these numbers. Problem:Now you get the number of such a group. Please use the minimum memory overhead and the minimum time overhead to find the repeated number. Because I didn't see the meaning of the question at first, I thought it was an ordered series, so I thought of a binary method. The bipartite method is a good method, but the prerequisite is wrong, and the natural result is wrong. It was seriously criticized by the head of Zhao. However, I am still worried about the time complexity of O (N) and decided to find an algorithm that is even a little faster overnight. Let's analyze it. |
|
|
The current algorithm is: (sum of 1001 digits)-(sum of 1000 digits) = (sum of 1001 digits)-n * (n + 1) /2 = duplicate number, and the sum needs to be 1000 cycles.
This algorithm can be established because of the sequenceYesComposed of 1-Consecutive NumbersOfTherefore, no matter how they are arranged, (the sum of the 1000 numbers) is increased from 1 to 1000. However, if these 1000 numbers are not consecutive, for example, 1000 numbers randomly selected from 1-, the algorithm is not true, because we cannot know which 1000 digits (the sum of the 1000 digits) are.
Since the given condition is 1-out of order, you can useContinuousThis feature improves the algorithm.
The simplest method should be: Open up an array list2 with a space of 1000, and place the 1001 numbers from the first one to the position of the number in list2.
For example:
List2 [list [0]-1] = list [0]
List2 [list [1]-1] = list [1]
Do this in sequence until the number to be saved already exists at the position corresponding to list2.
But this time I have clearly understood the requirements and cannot open up new spaces.
Although new space cannot be opened up, the idea is already available, that isUsing the correspondence between continuity and IndexesThe specific algorithm is described as follows:
1. Retrieve the number at the first position: p1 = list [0]
2. mark the first position: list [0] = 0
3. Retrieve the number at the position p1: p2 = list [p1]
4. Mark position p1: list [p1] = 0
5. Retrieve the number at the p2 position: p3 = list [p2]
6. Mark p2 position: list [p2] = 0
.............
Continue until the next position is marked, and the number is found.
The reason is:The repeated number finally needs to access his own location for the second time. When he accesses it, he finds that his location has been accessed by the previous one, and he knows that he is not the only one.
I don't know the name of this algorithm. Can it be called a roaming algorithm?
In the best case, the number of cycles is 1, for example, [1000,...].
In the worst case, the number of cycles is 1000, for example, [, 3 ......].
On average, the number of cycles is N/2, although the order of magnitude is still O (N), but on average, it is still twice faster than the previous summation method.
The following code is cute Python:
#! /Usr/bin/python
#-*-Coding: GBK -*-
Import random
# Generate a series
Armr_length = 10001
List = range (1, arr_length)
# Add a random number
Rnd = random. randrange (1, arr_length)
List. append (rnd)
Print '\ n repeated numbers:' + str (rnd)
# Disordered order
Random. shuffle (list)
# Start searching algorithms
Count = 0
Idx = 0
While (list [idx]! = 0 ):
Count = count + 1
Temp = list [idx]
List [idx] = 0
Idx = temp
Print "found: % d, loop % d times" % (temp, count)
The result of multiple operations is as follows:
// ================================================ ====