In less-than-linear time, find the duplicate in a sorted array

前端 未结 7 1463
名媛妹妹
名媛妹妹 2020-12-31 11:00

Today, an interviewer asked me this question. My immediate response was that we could simply do a linear search, comparing the current element with the previous element in t

相关标签:
7条回答
  • 2020-12-31 11:03

    The example array is a little bit different from your question. Since n is the length of array and there are one and only duplicate in array, the value of each element in array should be in [0,n-1].

    If that is true, then this question is the same one with How to find a duplicate element in an array of shuffled consecutive integers?

    The following code should find the duplicate in O(n) time and O(1) space.

    public static int findOnlyDuplicateFromArray(int[] a, boolean startWithZero){
        int xor = 0;
        int offset = 1;
        for(int i=0; i < a.length; i++){
            if(startWithZero)
                xor = xor ^ (a[i] + offset) ^ i;
            else
                xor = xor ^ a[i] ^ i;
            }
            if(startWithZero)
                xor = xor - offset;
        return xor;
    }
    
    0 讨论(0)
  • 2020-12-31 11:09

    Difference between sum of given array elements and sum of 0 to n-1 natural numbers gives you the duplicated element. Sum of 0 to n-1 elements is (N * N-1)/2 example array is [0,1,2,3,4,5,6,7,8,8,9] sum of 0 to 9 natural numbers is : 45 sum of given array elements : 53 53-45 = 8 Which is the duplicated element

    0 讨论(0)
  • 2020-12-31 11:15

    I attempted to come up with a divide-and-conquer algorithm to solve this, but I'm not confident that it was the right answer.

    Sure, you could do a binary search.

    If arr[i/2] >= i/2 then the duplicate is located in the upper half of the array, otherwise it is located in the lower half.

    while (lower != upper)
        mid = (lower + upper) / 2
        if (arr[mid] >= mid)
            lower = mid
        else
            upper = mid-1
    

    Since the array between lower and upper is halved in each iteration, the algorithm runs in O(log n).

    ideone.com demo in Java

    0 讨论(0)
  • 2020-12-31 11:15
    #include <bits/stdc++.h>
    using namespace std;
    
    int find_only_repeating_element(int arr[] , int n){
    int low = 0;
    int high = n-1;
    while(low <= high){
        int mid = low + (high - low)/2;
        if(arr[mid] == arr[mid + 1] || arr[mid] == arr[mid - 1]){
            return arr[mid];
        }
        if(arr[mid] < mid + 1){
            high = mid - 2;
        }else{
            low = mid + 1;
        }
       }
       return -1;
    }
    
    int main(int argc, char const *argv[])
    {
    int n , *arr;
    cin >> n;
    arr = new int[n];
    for(int i = 0 ; i < n ; i++){
        cin >> arr[i];
    }
        cout << find_only_repeating_element(arr , n) << endl;
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-31 11:17

    How about that? (recursion style)

    public static int DuplicateBinaryFind(int[] arr, int left, int right)
    {
       int dup =0;
    
       if(left==right)
       {
          dup = left;
       }
       else
       {
            int middle = (left+right)\2;
            if(arr[middle]<middle)
            {
              dup = DuplicateBinaryFind(arr,left, middle-1);
    
            }
            else
            {
               dup = DuplicateBinaryFind(arr, middle+1, right);
            }
       }
    
       return dup;
    
    }
    
    0 讨论(0)
  • 2020-12-31 11:20

    If no number is missing from the array, as in the example, it's doable in O(log n) with a binary search. If a[i] < i, the duplicate is before i, otherwise it's after i.

    If there is one number absent and one duplicate, we still know that if a[i] < i the duplicate must be before i and if a[i] > i, the absent number must be before i and the duplicate after. However, if a[i] == i, we don't know if missing number and duplicate are both before i or both after i. I don't see a way for a sublinear algorithm in that case.

    0 讨论(0)
提交回复
热议问题