![](/img/trans.png)
[英]Alternative O(N^2) time complexity with O(1) space complexity for finding distinct values in array
[英]Find missing numbers in array, time complexity O(N), space complexity O(1)
給出一個n個唯一整數0 <= x_i <2 * n的數組。 打印此數組中不存在的所有整數0 <= x <2 * n。
例:
find_missing([0])= [1]
find_missing([0,2,4])= [1,3,5]#因為所有數字都是[0,1,2,3,4,5]
find_missing([])= []
find_missing([0,1,4,5])= [2,3,6,7]#因為所有數字都是[0,1,2,3,4,5,6,7]
怪癖是關於要求:
時間復雜度O(n) - 但是應該有一些與輸入大小無關的固定常數C,這樣數組的每個元素都被寫入/讀取<C次,所以對數組進行基數排序是不行的。
空間復雜度O(1) - 你可以修改初始數組,BUT sorted(initial_array)必須等於sort(array_after_executing_program)並且你不能在這個數組中存儲范圍[0,2n]之外的整數(想象它是uint32_t的數組) )。
我看到了很多復雜的解決方案,但后來我發現了這個:
public void printNotInArr(int[] arr) {
if(arr == null)
return null;
int len = arr.length;
int max = 2 * len;
for(int i = 0; i < len; i++) {
System.out.println(max - arr[i] - 1);
}
}
我相信這是最好的解決方案,但我不確定。 我想知道為什么那不起作用。
正如@ LasseV.Karlsen指出的那樣,[0,3]是一個簡單的反例,展示了該解決方案不起作用的方式。 然而,這是一個非常簡單的解決方案(在Python中):
def show_missing(l):
n = len(l)
# put numbers less than n into the proper slot
for i in range(0,n):
while l[i]<n and l[i]!=i:
j = l[i]
l[i] = l[j]
l[j] = j
for i in range(0,n):
if l[i]!=i:
print('Missing %s'%i)
# put numbers greater than n into the proper slot
for i in range(0,n):
while l[i]>=n and l[i]!=i+n:
j = l[i]
l[i] = l[j-n]
l[j-n] = j
for i in range(0,n):
if l[i]!=i+n:
print('Missing %s'%(i+n))
這個想法很簡單。 我們首先重新排列元素,以便每個小於n的值j存儲在索引j處。 然后我們可以通過數組並輕松挑選出缺少的n以下的數組。
然后,我們重新排列元素,使得大於或等於n的每個值j都存儲在索引jn處。 同樣,我們可以通過數組並輕松挑選出大於或等於n的數組。
由於僅使用幾個局部變量,因此滿足O(1)空間復雜度。
由於嵌套循環,O(n)時間復雜度有點難以看出,但是要表明我們從不交換n個元素並不太難,因為一個新元素被放入其適當的位置交換。
由於我們只交換了數組的元素,因此也滿足了所有原始元素仍在數組中的要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.