簡體   English   中英

如何以 O(logn) 時間復雜度解決這個問題

[英]How to solve this problem in O(logn) time complexity

問題陳述:給定一個排序的整數數組,從給定的數組中找到不重復的 integer。 數組中只有 1 個不重復的 integer,其他 integer 范圍為 2。

輸入:[1,1,2,2,4,5,5] Output:4

輸入:[10,10,12,12,15,15,16,18,18] Output: 16

任何人都可以幫助我以 O(log N) 時間復雜度解決這個問題嗎?

注意:N是數組的長度

更新

已經指出原始代碼獲取數組的切片,如果這是通過副本完成的,則復雜度為O(n) 因此,這里是使用指向數組的指針的代碼版本:

Java:

public static int singleton(int[] arr, int lo, int hi) {
    if (hi == lo) return arr[hi];
    int m = (hi + lo) / 2;        
    if (m % 2 == 1) {
        if (arr[m] == arr[m-1]) return singleton(arr, m+1, hi);
        if (arr[m] != arr[m+1]) return arr[m];
        return singleton(arr, lo, m-1);
    }
    else {
        if (arr[m] == arr[m+1]) return singleton(arr, m+2, hi);
        if (arr[m] != arr[m-1]) return arr[m];
        return singleton(arr, lo, m);
    }
}      
    
public static void main(String args[])
{
    System.out.println(singleton(new int[]{ 1,1,2,2,4,5,5 }, 0, 6));
    System.out.println(singleton(new int[]{ 10,10,12,12,15,15,16,18,18 }, 0, 8));
    System.out.println(singleton(new int[]{1,2,2,5,5,6,6,7,7}, 0, 8));
    System.out.println(singleton(new int[]{1,1,2,5,5,6,6,7,7}, 0, 8));
    System.out.println(singleton(new int[]{10,10,12,12,15,15,16,16,18}, 0, 8));
}

Python:

def singleton(arr, lo, hi):
    if (hi == lo):
        return arr[hi]
    m = (hi + lo) // 2
    if (m % 2 == 1):
        if (arr[m] == arr[m-1]):
            return singleton(arr, m+1, hi)
        if (arr[m] != arr[m+1]):
            return arr[m]
        return singleton(arr, lo, m-1);
    else:
        if (arr[m] == arr[m+1]):
            return singleton(arr, m+2, hi)
        if (arr[m] != arr[m-1]):
            return arr[m]
        return singleton(arr, lo, m);

原始答案

因為您知道數組中的所有其他整數恰好出現兩次,所以您可以進行二進制搜索以找到僅出現一次的值。 您需要查找數組的中點並確定 singleton 是出現在該數字之前、之后還是該數字。 如果它在之前或之后,繼續搜索,但只搜索數組的那部分(最多一半)。 這是O(logn) 在 python 中(注意:當我最初回答這個問題時,它沒有用java標記 - 我隨后添加了一個 java 解決方案,您可以將其實現為:

def singleton(arr):
    m = len(arr) // 2
    if (m == 0):
        return arr[0]
    if m % 2 == 1:
        if arr[m] == arr[m-1]:
            return singleton(arr[m+1:])
        if arr[m] != arr[m+1]:
            return arr[m]
        return singleton(arr[:m])
    else:
        if arr[m] == arr[m+1]:
            return singleton(arr[m+2:])
        if arr[m] != arr[m-1]:
            return arr[m]
        return singleton(arr[:m+1])

示例用法:

print(singleton([1,1,2,2,4,5,5]))
print(singleton([10,10,12,12,15,15,16,18,18]))
print(singleton([1,2,2,5,5,6,6,7,7]))
print(singleton([1,1,2,5,5,6,6,7,7]))
print(singleton([10,10,12,12,15,15,16,16,18]))

Output:

4
16
1
2
18

我不是 java 專家,所以這可能不是最有效的方法,但它確實有效:

public static int singleton(int[] arr) {
    int m = arr.length / 2;
    if (m == 0) return arr[0];
    if (m % 2 == 1) {
        if (arr[m] == arr[m-1]) return singleton(Arrays.copyOfRange(arr, m+1, arr.length));
        if (arr[m] != arr[m+1]) return arr[m];
        return singleton(Arrays.copyOfRange(arr, 0, m));
    }
    else {
        if (arr[m] == arr[m+1]) return singleton(Arrays.copyOfRange(arr, m+2, arr.length));
        if (arr[m] != arr[m-1]) return arr[m];
        return singleton(Arrays.copyOfRange(arr, 0, m+1));
    }
}      
    
public static void main(String args[])
{
    System.out.println(singleton(new int[]{ 1,1,2,2,4,5,5 }));
    System.out.println(singleton(new int[]{ 10,10,12,12,15,15,16,18,18 }));
    System.out.println(singleton(new int[]{1,2,2,5,5,6,6,7,7}));
    System.out.println(singleton(new int[]{1,1,2,5,5,6,6,7,7}));
    System.out.println(singleton(new int[]{10,10,12,12,15,15,16,16,18}));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM