给出n个物品,判断是否有超过一半的物品是相同的。
前提是,两个物品只有放到一个特殊的装置中才能判断是否相同。
Θ(n^2):brute force
对每一个物体遍历
Θ(nlogn):分治,下面的代码纯属表达思想用,没有测试!!!
int divide(int *a,int n) { if(n == 2) { if(a[0] == a[1]) { return a[0]; } return EMPTY; } int ca = divide(a,n/2); int cb = divide(a + n/2.n - n/2); if(ca != EMPTY) { if(ca is majority in a[n/2 ... n-n/2]) { return ca; } } if(cb != EMPTY) { if(cb is majority in a[0...n/2]) { return cb; } } return EMPTY; }Θ(n):规模下降
Lemma:如果两个物品不同那么在去掉这两个物品的剩余物品中,如果存在Majority
元素,那么这个元素也是去掉之前的解.
设考虑要去掉的两个物品是A,B
如果A,B都不是Majority元素,那么在去掉A,B之后Majority元素一定不变
如果A是Majority元素,那么去掉两个元素之后,在n-2个物品中原来的Majority物品个数
由n/2 + 1变为 n/2,依然在n-2个物品中占大多数
贴<<Algorithms Design Techniques and Analysis>>上的代码,哥亲自输入的,
我的技术博客http://www.cppblog.com/schindlerlee
Algorithm 5.9 MAJORITYInput:An array A[1...n] of n elements.Output:The majority element if it exists:otherwise non. 1. c ← candidate(1) 2. cout ← 0; 3. for j ← 1 to n 4. if A[j] == c then count ← count + 1 5. end for 6. if count > ⌊n/2⌋ then return c 7. else return none 8. 9. Procedure candidate(m)10. j ← m;c ← A[m];count ← 111. while j < n and count > 012. j ← j + 113. if A[j] == c then count ← count + 114. else count ← count - 115. end while16. if j == n then return c17. else return candidate(j + 1)