寻找多数元素(主元素)
问题:
有整型数组a[1…n],如果整数x在数组a中出现的次数多于半数,则x称为多数元素。
初级方法:
- 计算每一个元素出现的次数,算法复杂度O(NlogN)
- 可以寻找中间值元素,因为多数元素在序列中必为中间值元素,时间复杂度是O(n)
分析此问题:
容易证明引理:在原序列中去除两个不同的元素后,那么在原序列中的多数元素在新序列中还是多数元素。
因此在以上引理的支持下,规模为n的问题就规约为求解规模为n-2的问题,于是我们可以得到一个时间复杂度也是O(n)、但是隐藏常数会比寻找中间值的方法要小的算法。
算法基本思路:
(1)在寻找多数元素的过程中,将计数器初始化为1,遇到相同元素则计数器加1,遇到不同元素则计数器减1,一直到计数器等于0或遍历完整个序列。由此可见,计数器的值表示当前元素抵消掉不同元素后的出现次数;
(2)当计数器在遍历完整个序列前就已经是0,则忽略掉已经遍历过的元素(可以看作两两抵消不影响序列中的多数元素),跳到下一个元素然后计数器重新置1,重复上述步骤,一直到遍历完整个序列;
(3)当遍历完整个序列后,算法会返回一个值,此时我们还需要检测一次这个值是否真的是多数元素,即遍历统计一次。这一步不可或缺。因为上述两个步骤到了遍历完序列后必将返回一个值,无论序列有无多数元素。此值存在两种情况,第一,它真的是多数元素;第二,它只是序列后面的某个元素刚好抵消完序列。所以我们必须检测一次。
算法的实现
寻找候选者算法:
int Candidate(int* A, int m , int n)
{//寻找A[m...n]中多数元素候选者c=A[m];count=1;for(j=m+1;count>0&&jif(A[j]==c)count++;else count--;}if(j==n)return c;elsereturn canditate(j); //对A[j...n]寻找多数元素候选者。
}
寻找数组多数元素的算法
bool Majority(int* A, int n, int* major) {c = conditate(A, 0, n-1);for (i=0; iif (A[j] == c)count++;if ( count > n/2 ){*major = c;// major即为所求return 1;}else return 0; //返回0表示不存在多数元素
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
