Leetcode 287. Find the Duplicate number O (n) solution and O (NLOGN) solution

Source: Internet
Author: User
Tags repetition
Find the Duplicate number

Topic Connection: Find the Duplicate number descript

Given an array nums containing n + 1 integers where each integer is between 1 and N (inclusive), prove that at least one D Uplicate number must exist. Assume that there are only one duplicate number, find the duplicate one.

Note:
You must the Modify the array (assume the array was read only).
You must use only constant, O (1) Extra space.
Your runtime complexity should is less than O (N2).
There is a duplicate number in the array, but it could was repeated more than once. Test Instructions

In an array of n+1 elements consisting of 1-n, find out which element is duplicated, only 1 elements will repeat, but the number of repetitions may be more than 1 times. There are limitations on time complexity and space complexity. Thinking of solving problems

This problem is a lot of restrictions, it is really the test of IQ ... At first I was analyzing the topic from the angle of summation and averaging, and found that it was impossible to give up because multiple situations could be caused by multiple repetitions. Finally, discussion with the students and online access to get two solutions, one is the dichotomy to find the repetition number, the complexity O (NLOGN), the other is the mapping method + fast pointer, complexity O (n). Dichotomy O (NLOGN)

If no elements are duplicated, the number of elements on the left and right sides of the N/2 should be equal. Based on this idea, for 1-n, iterate over this array, record the number of elements less than or equal to N/2, if greater than N/2, the number of repetitions is less than or equal to N/2, otherwise greater than N/2. Next, continue to find the appropriate interval for the two points. Because the array needs to be traversed each time, the complexity is O (NLOGN).

Class Solution {public
:
    int findduplicate (vector<int>& nums) {
        int n=nums.size ()-1;
        int low=1;
        int high=n;
        int mid;
        while (Low
Map-Seeking method + fast-speed pointer O (n)

This algorithm is really magical ah, I think the people are not good ... After a few discussions with my classmates, the theoretical correctness of the algorithm proved, but also here and everyone to share, to help you understand the algorithm.
The first element of Num[i], we put k=num[k] as an operation, the basic idea of this algorithm is to find a repeating element by iterating through a slow pointer with one operation at a time and a fast pointer of two operations each time. First, since the subscript is starting at 0, the subscript is a sequence of 0 to N, mapped to the number of n+1 that contain duplicates. Then due to the existence of duplicate elements, so there must be more than two subscript pointing to the same number, which will result in multiple iterations, the fast and slow pointer will enter a loop. Two pointers at different speeds on the ring are bound to meet at a certain position. As shown in the following illustration:

Where a represents the number of repetitions (it can be shown that two pointers must be from a repeating element into the ring) and B represents the point where the two pointers meet each other. At the beginning both hands go first step a after entering the ring, the slow pointer walked x (x < l,l for each lap length, x may be slow pointer walk a lot of laps after a circle of distance, in fact, can prove that the slow pointer must not go to a circle and the fast pointer met, that is, the following k1=0) step and the fast pointer met. Suppose that the slow pointer and the fast pointer walk the K1 and K2 rings on the ring, respectively:
2[a+ (k1l+x)]a+2k1l+xa+xa+l−baa=a+ (k2l+x) =k2l= (K2−2K1) l= (K2−2K1) l= (k2−2k2−1) l+b=cl+b \begin{align} 2[a+ (k_1L+x)] &=a+ (k_2l+x) \ a+2k_1l+x&=k_2l \ a+x&= (k_2-2k_1) l \ a+l-b&= (k_2-2k_1) l \ \ a&= (k_2-2k_2-1) L+b \ A &=cl+b \end{align}
What is the use of this conclusion?
Oh, my God, that's very useful. If we let a new slow pointer start from the beginning, while the old slow pointer from the encounter position continue to walk, after the old pointer has gone to the C-circle, will be bound with the new pointer at the repetition point of the encounter, this found the duplicate element is which. The implementation code is as follows.

Class Solution {public
:
    int findduplicate (vector<int>& nums) {
        int fst=0,slow=0;
        do{
            Fst=nums[nums[fst]];
            Slow=nums[slow];
        } while (Fst!=slow);
        fst=0;
        while (Fst!=slow) {
            fst=nums[fst];
            Slow=nums[slow];
        }
        return FST;
    }
;

In fact, you will be more aware of the process of presenting this algorithm yourself on paper.

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.