題目:給定乙個無序的整數陣列,怎麼找到第乙個大於
0,並且不在此陣列的整數。比如
[1,2,0]
返回3, [3,4,-1,1]返回2
。最好能
o(1)
空間和o(n)
時間。
該題在首先,給定的整數陣列可能包含負數,而且正數的範圍也可以超過n,所以最普遍的情況應該如下:36
-1-24
演算法的基本思想是只考慮範圍在
0的正整數,並將其歸位到其應該在的位置,這和
陣列統計分析非常類似。當在這個範圍內的所有正整數都歸位以後,我們再次從位置1開始遍歷陣列,第乙個a[i]!=i即為所求的結果。道理也很簡單,當我們將所有在
0的正整數歸位以後,出現過的正整數都會在其正確位置,沒有出現的元素會被其他
a[i]<=0
或者a[i]>n
的元素所佔據,因而通過條件a[i]!=i判斷所得的值即為所求。
此外,陣列中還可能會出現在
0範圍內的重複元素,這會對演算法產生影響嗎?不會。即使出現重複元素,該元素也不可能被選為答案。首先,重複元素裡面肯定會有乙個會在正確的位置,而其他的重複元素只可能出現在缺失元素的位置。在遍歷的過程中,當我們遇到乙個重複元素時,如果其不在正確位置,我們選擇該元素所在的位置,該位置肯定和重複元素不一樣;如果其在正確位置,則我們直接跳過該元素判斷下乙個位置即可,因為其已經正確歸位。所以不管哪種可能,我們都不會將重複元素選出作為結果。
至於範圍
a[i]<=0
或者a[i]>n
的元素,不管其是否重複,我們都不對其進行交換操作,它們也只會佔據未出現元素的位置。不過它們有可能被宰範圍
0內的正整數交換一次,然後停止交換。
根據上面的分析,我們可以知道該演算法和
陣列統計分析非常類似,演算法的偽**如下:
for i=1:n
while canswap(i) do swap(i);
上述偽**的含義是,從第乙個位置開始判斷是否需要交換,如果能交換就一直交換直到該位置滿足以下三種情況時停止,然後判斷下乙個位置:1) a[i]<=0;2) a[i]>n;3) a[a[i]]==a[i]。實際的**如下:
int lostnum(int *a,int n)
}for(int i=1;i對於演算法的複雜度分析,可參考之前的分析,雖然有兩層迴圈,但其實是乙個o(n)複雜度的演算法,證明可以利用平攤分析。
缺失的數字
給定乙個包含 0,1,2,n 中 n 個數的序列,找出 0 n 中沒有出現在序列中的那個數。示例 1 輸入 3,0,1 輸出 2示例 2 輸入 9,6,4,2,3,5,7,0,1 輸出 8package 陣列 auther kevin date classname numbermissing des...
數字遊戲 尋找缺失的數字
演算法專題導航頁面 演算法專題 應用場景 數字遊戲 尋找缺失的數字 尋找兩個排序陣列 長度相等 的上中位數 題目 程式猿小明來自於乙個游牧家庭,家裡有乙個大大的牧場和成群結隊的牛羊,為了便於管理羊群,小明決定對每只綿羊進行編號標記,最終剛好用完100個號碼 1 100 小明的日常生活簡單的有點枯燥 ...
64 缺失數字
題目描述 一開始擼出來的 class solution if nums 0 1 return nums i 1 後續改進的 直接使用兩個for迴圈,需要注意的是 第乙個for迴圈是將s這個布林陣列進行初始化,因為預設是false,第二個for迴圈是找出s這個陣列中的為false的下標,那麼就返回這個...