演算法學習-第一個缺失的正整數
題目
分析給定一個陣列A[0...N-1],找到從1開始,第一個不再陣列中的正整數。
如3,5,1,2,-3,7,14,8輸出4。
下面給出第四種方法的程式碼解法很多,如下:
1、可以暴力求解,從1遍歷到n,每次和陣列對比,找到第一個不在陣列中的,時間複雜度為O(N2)
2、可以優化一下演算法,先排序在進行2分查詢,時間複雜度為N*log(N)。
3、因為第一個缺失的正整數肯定小於等於N+1,所以可以申請N個空間,然後遍歷原陣列,將大於0,小於n的數在新申請的空間中對應的位置做標記,最後遍歷申請的空間,找到第一個不在申請空間中的資料,時間複雜度是O(N),空間複雜度是O(N)
4、將找到的元素放到正確位置上,如果最終發現某個元素一直沒有找到,則該元素即為所求。迴圈不變式:如果某命題初始為真,且每次更改後仍然保持該命題為真,則若干次更改後該命題仍然為真。
假定前i-1個數已經找到,並且一次存放在A[1,2,...,i-1]中,繼續考察A[i]:
若A[i]<i且A[i]>=1,則A[i]在A[1,2,...,i-1]中已經出現過,可以直接丟棄。若A[i]為負,則更應該丟棄它。
若A[i]>i且A[i]<=N,則A[i]應該置於後面的位置,即將A[A[i]]和A[i]交換。若A[i]>N,由於缺失資料>=N,則A[i]丟棄。若A[A[i]]=A[i],顯然不比交換,直接丟棄A[i]即可。
若A[i]=i,則A[i]位於正確的位置上,則i加1,迴圈不變式擴大,繼續比較後面的元素。
演算法描述:
若A[i]=i,i加1,繼續比較後面的元素。
若A[i]<i或A[i]>N或A[A[i]]=A[i],丟棄A[i]
若A[i]>i,則將A[A[i]]和A[i]交換。
丟棄A[i]即將A[N]賦值給A[i],然後N減1.
int FirstMissNumber(int* a, int size)
{
a--; // 從1開始
int i = 1;
while (i <= size)
{
if (a[i] == 1)
{
i++;
}
else if ((a[i] < i) || (a[i] > size) || (a[i] == a[a[i]]))
{
a[i] = a[size];
size--;
}
else
{
int ntmp = a[a[i]];
a[a[i]] = a[i];
a[i] = ntmp;
}
}
return i;
}
相關文章
- 演算法41. 缺失的第一個正數演算法
- LeetCode 41. 缺失的第一個正數LeetCode
- 【陣列】1539. 第 k 個缺失的正整數(簡單)陣列
- JS演算法之找出缺失的整數JS演算法
- leetcode:41. 缺失的第一個正數(困難,陣列)LeetCode陣列
- 排序演算法-N個正整數排序排序演算法
- 演算法學習記錄十(C++)--->數值的整數次方演算法C++
- 求正整數
- 查詢正序排列的List中缺失的日期資料的一個演算法演算法
- 實現一個原子的正整數類:AtomicPositiveInteger
- leetcode:確實的第一個整數(java)LeetCodeJava
- 如何在1到100的整數陣列上找到缺失的數字陣列
- 【JAVA習題六】輸入兩個正整數m和n,求其最大公約數Java
- Java判斷一個正整數是不是2的乘方Java
- JQuery 判斷 正整數jQuery
- 第一個JavaScript的例子學習JavaScript
- python將輸入的一個正整數分解質因數(map)Python
- 演算法學習之路|個位數統計演算法
- Python:判斷一個正整數是否為迴文數Python
- 輸入一個整數,返回這個整數的位數
- c語言:輸入任意10個正整數,按照升序排序輸出:(冒泡演算法)C語言排序演算法
- 演算法學習之路|寫出這個數(20)演算法
- 運籌學-整數規劃IP演算法演算法
- 2034 整數的個數
- 求兩個正整數的最大公約數與最小公倍數--C#實現C#
- 陣列中未出現的最小正整數陣列
- 【C語言】編寫一個函式,將一個數字字串轉換成該字串對應的數字(包括正整數、負整數)。C語言函式字串
- 【演算法學習】組合數學演算法
- 開始我的第一個PHP學習PHP
- pandas學習task07缺失資料
- js 將負數或小數轉成正整數JS
- 演算法學習之路|朋友數演算法
- 演算法學習之路|數零壹演算法
- JavaScript正規表示式校驗非零的正整數例項JavaScript
- 求陣列中未出現的最小正整數陣列
- 02_Python學習筆記之統計整數二進位制中1的個數Python筆記
- 新手學習如何完全退出整個應用
- 正整數表單校驗規則