最小沒出現的整數

2022-09-04 05:54:07 字數 2495 閱讀 6471

**自:

題目

#面試題#給定乙個無序的整數陣列,怎麼找到第乙個大於0,並且不在此陣列的最小整數。比如[1,2,0] 返回 3, [3,4,-1,1] 返回 2。最好能o(1)空間和o(n)時間。

**解法:直接考慮這個問題是比較困難的。不如先換個簡單的問題。

問題1

給定乙個陣列,長度為n,除a[0]以外,其他元素都是a[i] == i。那麼請找出第乙個大於0,且不在此陣列中的最小整數。

答案就是:  n + (a[0] == n);

問題2

給定乙個陣列,長度為n,某幾個位置的元素滿足 a[x] < 0 或者 a[x] > n,餘下的元素都滿足a[i] == i。那麼請找出第乙個大於0,且不在此陣列中的最小整數。

答:很明顯:當x的值限定為0時。就變成了問題1。

除此之外,這個問題的解也容易求得。

情況1: 首先從1~n開始掃瞄,當發現i != a[i]時,直接返回i。此時的i必定是最小的未出現的整數。

情況2: 當掃瞄完1~n之後,那麼就回歸至問題1了。

1

for (i = 1; i < n; ++i)

4return (n + (n == a[0]));

問題3

當給出問題2之後,就需要考慮如何把原題目轉換成為問題2了。

實際上要完成的任務就變成了,如何把乙個陣列中的元素元神歸位。也就是讓a[i] == i。如果能讓這些元素元神歸位,那麼就轉換成為問題2了。就很容易求解了。

演算法如下:

我們從後往前掃瞄,i = n - 1 to 0;

step1如果發現a[i] < 0 || a[i] > n; 則 continue;

step2 如果發現a[i] == a[a[i]]; 則continue;

step3 如果發現0 < a[i] < n

說明需要將a[i]元神歸位。也就是放到a[a[i]]上去。

swap(a[i], a[a[i]]).

再跳轉至step2。

note: 需要注意一種有重複數的情況,比如a[11] = 2, a[2] = 2。這時候,就不用進行交換了。直接處理下乙個元素。

可以給出**:

1

int i =n, t, temp;

2if (!a || n <= 0) return -1;3

4while ((--i) >= 0

) 12 }

好吧,到現在為止,原題已經變得很簡單了。可以直接給出**了。

原題解答

1

int find(int *a, int

n) 13}14

15for (i = 1; i < n; ++i)

16if (a[i] != i) return

i;17

18return (n + (a[0] ==n));

19 }

演算法複雜度分析

這裡再加上對演算法複雜度的分析。演算法的複雜度在下面這段**看起來。唔~~很難說清楚到底複雜底是多少。

我們不妨回歸到問題本身。把一些條件分析清楚:

條件1、對於給定的乙個陣列。元神歸位數目是有限的。假定為k。這個k表示的是,當處理完成之後,a[i] == i的數目。

k的範圍是固定的: 0 <= k < n。

條件2、對於每個元素而言,while (0 < a[i] && a[i] < n && i != a[i]) 這個while 迴圈裡面,每交換一次,就會使得乙個元神歸位。如果交換了xi次,就會使得xi個元神歸位。

這個是很容易搞清楚的。因為每次交換的效果,都是讓某個元神歸了位。

比如a[11] = 5, a[5] = 2, a[2] = 0;

第一次交換: a[11] = 2, a[5] = 5, a[2] = 0;

第二次交換: a[11] = 0, a[5] = 5, a[2] = 2;

條件3、對於整個陣列而言,元神歸位的數目k應該是滿足:

x0 + x1 + x2 + x3 + ..... + xn-1 = k

這也就是說交換k次。

注意啊: 不是每個i都會交換k次。而是所有的i交換次數的總和,應該是k次。

可以想象一種極端的情況,比如,當i=n-1的時候,置換次數最多。剛好把所有的元神都歸位了。那麼從i = n - 2開始,就再也不會進入到裡面的while迴圈中去了。

再例如:如果i=n-1的時候,使得2個元神歸了位。那麼從 i = n-2 ~ 0,則只需要讓k-2個元神歸位了。因為已經歸位的,是不用再去處理的。

想到這裡,你應該明白了,下面這段**的複雜度是o(n) + o(k)。由於0<=k < n。所以複雜度是o(n)。也就是線性時間完成了任務

面試題整理 最小沒出現的整數

題目 面試題 給定乙個無序的整數陣列,怎麼找到第乙個大於0,並且不在此陣列的最小整數。比如 1,2,0 返回 3,3,4,1,1 返回 2。最好能o 1 空間和o n 時間。解法 直接考慮這個問題是比較困難的。不如先換個簡單的問題。問題1給定乙個陣列,長度為n,除a 0 以外,其他元素都是a i i...

40億個非負整數中找到沒出現的數

要求這裡的非負整數是32位也就是0 2 32 1。最多用1gb的記憶體。如果只能用10mb的空間呢,只需要找到乙個沒有出現的數即可。首先先分析一下,40億個4b約為16gb這裡只用1gb,這裡要求注意是找出沒出現,這就和網頁過濾系統類似,出現與不出現兩個狀態 0和1 那麼我們就可以用bit陣列來確定...

陣列中未出現的最小正整數

陣列中未出現的最小正整數 給定乙個無序陣列arr,找到陣列中未出現的最小正整數 例如arr 1,2,3,4 返回1 arr 1,2,3,4 返回5 要求 時間複雜度為o n o n o n 空間複雜度為o 1 o 1 o 1 輸入描述 第一行為乙個整數n。表示陣列長度。接下來一行n個整數表示陣列內的...