寻找数组中的众数- 摩尔投票法

问题:在长度为n的数组中找出重复次数超过n/2的数(假设一定存在)。

存在O(n)的时间复杂度和O(1)的空间复杂度的解法,即摩尔投票法

摩尔投票法

摩尔投票法基于这样一个事实,当一个数的重复次数超过数组长度的一半,每次将两个不相同的数删除,最终剩下的就是要找的数。

JAVA代码


    public int majorityElement(int[] nums) {
        if(nums.length == 1) return nums[0];
        
        int moore = 0;
        int count = 0;
        
        for(int i = 0; i < nums.length; i++) {
            if(count == 0) {
                moore = nums[i];
            }
            if(nums[i] == moore) {
                count++;
            } else {
                count--;
            }
        }
        return moore;
    }

如果这个众数不一定存在的话,需要进行二次遍历判断。

类似的问题: 在长度为n的数组中找出重复次数超过n/3的数(不一定存在)。

同样的思路,使用两个虚拟数组,每次删除三个不同的数,最终虚拟数组中的两个数就是可能的答案,此时再遍历一遍数组,做一个验证即可。

#include<stdio.h>
#define LEN 8
int main(){
    int a[] = {1,2,1,2,3,3,1,2};
    int x, y, cx = 0, cy = 0;//两个虚拟数组
    for(int i = 0; i < LEN; ++i){
        if(x == a[i]) ++cx;
        else if(y == a[i]) ++cy;
        else if(cx == 0) x = a[i], cx = 1;
        else if(cy == 0) y = a[i], cy = 1;//这两个判断不能提前,因为可能把x,y赋为同一个值
        else --cx, --cy;
    }
    cx = 0,cy = 0;
    for(int i = 0; i < LEN; ++i){//锁定候选目标,遍历数组,计数,做验证
        if(a[i] == x) ++cx;
        else if(a[i] == y) ++cy;
    }
    if(cx > LEN/3){
        printf("超过1/3的数有:%d\n",x);
    }
    if(cy > LEN/3){
        printf("超过1/3的数有:%d\n",y);
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问题:在长度为n的数组中找出重复次数超过n/2的数(假设一定存在)。 存在O(n)的时间复杂度和O(1)的空间复杂...
    M_lear阅读 3,167评论 0 2
  • 前言 2. 实现 Singleton 3. 数组中重复的数字 4. 二维数组中的查找 5. 替换空格 6. 从尾到...
    Observer_____阅读 3,031评论 0 1
  • 1. 找出数组中重复的数字 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,...
    BookThief阅读 1,849评论 0 2
  • 提问: 给定一个int型数组,找出该数组中出现次数大于数组长度一半的int值。 解决方案: 遍历该数组,统计每个i...
    Jimmy5Zhang阅读 10,267评论 3 5
  • 两天把偷影子的人这本书看完了,是很好看的一本书。书中的小男孩没有名字,好像就寓意了这可能是我们每一个人。 男主小时...
    温暖的光y阅读 327评论 0 0