找出1到N中缺少的數?
《算法導論》中的練習題,
n-1個元素的數組A,含有1到n之間的n-1個數,找出缺少的那個數?
要求:O(n)
解法一:
sum = n*(n+1)/2;
sum減掉A中的每個元素,剩下的就是要找的數。
解法二:
利用異或運算,x^x==0
xor = 1^2^...^n;
xor異或A中的每個元素,最後得到的就是所求。
解法三:
增加一個空位A[n-1],將A[i]移到A[ A[i] ],
?
題目升級:
? 缺失兩個數,求出這兩個數。
思想:
? ?也是采用異或。
? ? 假設,缺失的數為s1和s2。則s1^s2=1^2^3.....^n^a[0]^a[1]^....a[n-3]。這個式子一目了然,無需多解釋。
問題是如何通過這個式子求出s1與s2的值。只要能求出一個值,比如說s1,則s2=s1^(s1^s2)。
? ?s1^s2的值必然不為0,則必然存在一位,s1與s2在此對應位不同。我們就可以按照此對應位是0或者1,將1-n分為兩堆,將a[0]-a[n-3]分為兩堆。
將該為為1的兩堆數相異或就能求出缺失的一個數。
? ?舉個例子。1-7中缺失3,4。轉化為二進制位:011和100。三位都不同,我們用最后一位來判別,將1-n和數組非為兩堆。
? 則結果為:
| 標志位(最后一位) | 1 | 0 |
| 1-n | 1、3、5、7 | 2、4、6 |
| a[0]-a[n-3] | 1、5、7 | 2、6 |
用標志位為1的數進行異或
?1^3^5^7^1^5^7=3。這樣就求出了一個缺失數。
// in case find two missing numbers, here size is 2 less than the range n void find_missing_number2 (int a[], int size, int& miss1, int& miss2) {miss1 = 0;miss2 = 0;int number=0;for (int i=0;i<size;i++)number ^= ((i+1)^a[i]);number ^= (size+1);number ^= (size+2); // now number will be miss1^miss2// find the binary 1 in numberint k = number - (number&(number-1));for (int i=0;i<size;i++) {if ( (i+1)&k )miss1 ^= (i+1);if ( a[i]&k )miss1 ^= a[i];}if ( (size+1) & k )miss1 ^= size+1;if ( (size+2) & k )miss1 ^= size+2;miss2 = number ^ miss1; }?
類似的問題:
1、1-1000放在含有1001個元素的數組中,只有唯一的一個元素值重復,其它均只出現一次。每個數組元素只能訪問一次,設計一個算法,將它找出來;
不用輔助存儲空間,能否設計一個算法實現?
2、給你n個數,其中有且僅有一個數出現了奇數次,其余的數都出現了偶數次。用線性時間常數空間找出出現了奇數次的那一個數。
3、給你n個數,其中有且僅有兩個數出現了奇數次,其余的數都出現了偶數次。用線性時間常數空間找出出現了奇數次的那兩個數。
轉載于:https://www.cnblogs.com/prajna/archive/2013/02/25/2932807.html
總結
以上是生活随笔為你收集整理的找出1到N中缺少的數?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sixxpack破解的文章!【转】
- 下一篇: 消除疑虑