摩爾衆數投票算法
Moore majority vote 算法
摩尔投票法基于这样一个事实:
当一个数的重复次数超过数组长度的一半,每次将两个不相同的数删除,最终剩下的就是要找的数。
我们采用一个虚拟数组(在实现中可以使用两个变量代替,一个代表当前数组内元素的个数,另一个储存当前的候选数)来储存候选的众数。当遇到相同的数的时候向虚拟数组中加入当前的候选数,遇到不同的数的时候从虚拟数组中删除一个候选数。如果虚拟数组大小为0,向虚拟数组中加入当前位置的数作为候选数。遍历完成后数组中剩余的元素就是众数。
因为众数大于数组的一半,哪怕最极端的其它数全都相同,众数也能在数组中剩余不少于2m-n(其中m为众数的数量,n为数组大小)。
1 | int majorityElement(vector<int>& nums) { |
扩展
求在长度为n的数组中出现次数超过n/3的数
明显的,长度超过n/3的数最多只有2个。
按照摩尔投票法的思路,我们可以设置两个虚拟数组,最终两个数组中的数就是满足条件的数(如果题目没有说明一定存在,则可以进行一轮遍历验证)
如下方代码所示逻辑,相当于平均每次访问了3个数字,因为所求数字重复次数超过了n/3,所以按平均的情况每次访问时都会存在有所求数字保留在虚拟数组中,即:一定会占据虚拟数组一个栏位。
1 | void getSuitableNumber(vector<int> arr) { |
长度为n的数组中出现次数超过n/k的数
按照之前的逻辑,只需设置k-1个虚拟数组,最后留下的数字即可能是满足条件的数。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Sugar Code!