[英]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.