Find the number of ten thousand two repetitions, fast binary search O (logN) (rpm)

Title: 1-1000 on the array contains 1001 elements, only one element of value only repeat, all other only once. Each array element can only be accessed once, to design an algorithm to find it out; without an auxiliary storage space, the ability to design an algorithm?

First, an orderly situation

1,001 number, arranged in the order from small to large, of which only two numbers is repeated. Of course, as ordered, two numbers must have been installed next to the.
The requirement is subject with minimal memory overhead, minimal time to find out the cost of duplicate numbers

In Mobei Te  's blog, his algorithm is (1001 numbers and) - (1000 numbers and) = repeat numbers, this algorithm idea is simple, but time complexity is the highest, were carried out in 2000 time cycles, the other algorithm message is also essentially a linear search linear search time complexity is O (N), for purposes of this question, the best of luck to find the first time, the worst luck , looking for 1000, an average of 500 times looking for.

static void Main(string[] args)
        {
           int[] list = new int[1001];
           for (int i = 1; i < 1001; i++)
          {
                list[i - 1] = i;
           }

            Random random = new Random();
            list[1000] = random.Next(1, 1000);
            int sum1 = 0;
            int sum2 = 0;
            foreach (int i in list)
           {
               sum1 = sum1 + i;
            }
           for (int i = 1; i < 1001; i++)
            {
               sum2 = sum2 + i;
            }

          Console.WriteLine ( "duplicate numbers are:" + (SUM1 - SUM2) .ToString ());
            Console.Read();
        }

However, if we consider that this is an ordered sequence , and only two the number of repetitions, binary binary search to leap out, and there is understanding of data structures and algorithms people know binary search method is an ordered sequence the best search algorithm.
Specific ideas are:

  1. left=0
  2. right=10001
  3. If the value of the middle of the left and right position pos pos position number is equal, then:
  4. left = pos, otherwise:
  5. right=pos
  6. If the number (right-left> 1), then repeating steps 3) to 6) until the right-left = 1, pos is to find

1000 Just look for the number 10 times, 13 times the number of ten thousand, one hundred thousand number of 17 times, 20 times the number of one million, the time complexity of O (logN), very fast.

#!/usr/bin/python
# -*- coding: GBK -*-
import random

# Generates the number of columns, the number of ten thousand
arr_length=100001
list=range(1,arr_length)

# Insert a random number
rnd = random.randrange ( 1 arr_length)
list.insert(rnd-1,rnd)

Print ' \ n-number of repetition is: ' + STR (RND)
Print ' \ the n-Find '
 
# Started search algorithm   
left=0
right=arr_length
count=0

while ((right-left)>1):
    pos=(left+right)/2    
    count=count+1
    print '第 %d 次定位:%d' % (count,pos)    
    if (list[pos]==pos):
        right=pos
    else:
        left=pos    

Print ' \ n-Search Results: ' , List [left]

Note: First attach the original author of Python, find a time and then converted java

Second, the disorderly situation

The above algorithm is: (1001 and digital) - (1000 and digital) = (1001 and digital) - n * (n + 1 ) / 2 = repeat numbers 1000 cycles required sum.
This algorithm has been able to set up, because the sequence is a consecutive number from 1 to 1000 consisting of , therefore, no matter how they are arranged, (1000 numbers and) are from 1 to the 1000. However, if the 1000 numbers are not consecutive, such as from the 1-100000 different from each other randomly selected out of the 1000 number, then the algorithm does not hold, because we do not know (1000 Digital and) in the end is which 1000 figures.

Since the condition is now given out of order 1000, then we can take advantage of continuous This particularity to improve the algorithm.

The easiest way would be: re-opened a 1000 array list2 space, these 1001 numbers from the first start, turn into list2 number in his position
such as:
list2 [ List [0] -1] = List [0]
list2 [List [1] -1] = List [1]
in order to do so, until you want to save a number in the corresponding position list2 already exist, to find this number.
But this time I see the requirements, and can not open up new space.

Although not open up new space, but the idea has been, is the use of the corresponding relationship and the continuity index , specific algorithm described as follows:
1. Remove the digital first position: P1List = [0]
2, the first position mark: List [0] = 0
. 3, position numbers p1 removed: P2 = List [p1]
. 4, the position mark p1: List [p1] = 0
. 5, taken digital position p2: P3 = List [p2]
. 6, the marker position p2: List [p2] = 0
.............
order to do so, until the next location is marked looking after a digital to find.
The reason is: that duplicate numbers, and ultimately to visit his own position a second time, when he visited and found that the location had been visited on its own, and he knew he was not the only.

This algorithm What is the name I do not know, can not be called roaming algorithm?
In the best case, he number of cycles is 1, such as [1,1, .... 1000]
In the worst case, he number of cycles was 1000, for example [1,2,3 ... ... 1000, 1000]
average, his number of cycles is N / 2, although the magnitude is still O (N) level, but on average, still twice as fast than the previous summation method

 

#!/usr/bin/python
# -*- coding: GBK -*-
import random

# Generates the number of columns
arr_length=10001
list=range(1,arr_length)

# To add a random number
rnd = random.randrange ( 1 arr_length)
list.append(rnd)
Print ' \ n-number of repetition is: ' + STR (RND)

#mess up the order
random.shuffle(list)

# Started search algorithm 
count=0
idx=0  
while (list[idx]!=0):
    count=count +1
    temp=list[idx] 
    list[idx]=0
    idx=temp    

Print " Found:% d,% d cycle times " % (the TEMP, COUNT)

 

Note: First attach the original author of Python, find a time and then converted java

 

Reproduced in: https: //www.cnblogs.com/JoannaQ/archive/2013/03/19/2968458.html

Guess you like

Origin blog.csdn.net/weixin_34308389/article/details/93055977
Recommended