摩尔投票算法及其变种的应用(二)

k等分主元素问题:找出在一个长度为n的数组中存在出现次数大于\lfloor \frac{n}{k} \rfloor的元素
问题分析:首先可以确定的是,这样的元素数量最多存在k - 1个,该结论很容易得出,此处不再详细论证。该问题是主元素问题的扩展,同样可以使用摩尔投票法解决,当kn相比不大时,时间复杂度为O(n),空间复杂度为O(1)。下面以k = 3为例,设计并实现算法

思路与分析:在原始的摩尔投票法中,每次选出的是一组两个不相同的元素并删除,直到无法继续选出元素组,这样会使得主元素只可能在剩下的元素中存在,那么如果每次选出一组三个互不相同的元素呢?在这种情况下,无法继续选出元素组的原因可能是:1. 数组中无剩余元素;2. 数组中剩余元素只有两种取值;3. 数组中剩余元素只有一种取值

  • 数组中无剩余元素:说明n为3的倍数,由于找出元素并删除的操作进行了\frac{n}{3}次,而每次的三个元素互不相同,则每个元素最多只出现了\frac{n}{3}次,此时不存在k等分主元素
  • 数组中剩余元素只有两种取值:说明n3m, 3m + 13m + 2,同样地,无论是哪种情况,都能说明剩下的两个元素是唯一可能的两个k等分主元素。假设找出元素并删除的操作进行了k次,分析如下:
    • n3m时,一定有k \times 3 < n,而被删除的每个元素最多出现次数即为k,因此它们都不可能是k等分主元素
    • n3m + 13m + 2时,同样一定有k \times 3 < n,因此同理,被删除的元素都不可能是k等分主元素
  • 数组中剩余元素只有一种取值:同理,说明被删除的元素都不可能是k等分主元素,同时该数组中不再可能有两个k等分主元素,而是最多只有一个k等分主元素

算法实现:类似于一组包含两个元素的摩尔投票算法的实现,包含三个元素的摩尔投票算法使用两个变量和两个计数器去模拟每轮选出三个互不相同元素的过程,只是需要注意一些实现细节,并且最后不能省略对两个可能的k等分主元素的检验

int* majorityElement(int* nums, int numsSize, int* returnSize){
    int x;
    int y;
    int count_x;
    int count_y;
    int* res = NULL;
    int n;
    int i;
    
    res = (int *)malloc(2 * sizeof(int));
    n = 0;
    count_x = 0;
    count_y = 0;
    for(i = 0; i < numsSize; i++)
    {
        // 将原本的count == 0和nums[i] == x两个条件合并
        if((count_x == 0 || nums[i] == x) && nums[i] != y)
        {
            count_x++;
            x = nums[i];
        }
        else if(count_y == 0 || nums[i] == y)
        {
            count_y++;
            y = nums[i];
        }
        else
        {
            count_x--;
            count_y--;
        }
    }
    
    /* 对x和y需要进行额外的检测,因为不能保证x和y一定满足要求 */
    count_x = 0;
    for(i = 0; i < numsSize; i++)
    {
        if(x == nums[i]) count_x++;
    }
    if(count_x > numsSize / 3) res[n++] = x;
    
    count_y = 0;
    for(i = 0; i < numsSize; i++)
    {
        if(y == nums[i]) count_y++;
    }
    if(count_y > numsSize / 3 && x != y) res[n++] = y;
    
    *returnSize = n;
    return res;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 主元素问题:找出在一个长度为的数组中存在出现次数大于的元素,已知这样的元素一定存在 常见解法: 排序法:首先能确定...
    AsuraLG阅读 2,915评论 0 1
  • 1 初级排序算法 排序算法关注的主要是重新排列数组元素,其中每个元素都有一个主键。排序算法是将所有元素主键按某种方...
    深度沉迷学习阅读 5,338评论 0 1
  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 9,670评论 0 0
  • 最近在读< >时,了解到了很多常用的排序算法,故写一篇读书笔记记录下这些排序算法的思路和实现. 冒泡排序 冒泡排序...
    SylvanasSun阅读 3,991评论 0 0
  • 后金进攻朝鲜前后共花费三个多月时间,而这段时间里正面的明军没有任何大规模动作。 朝鲜的求援,明东江镇总兵毛文龙的求...
    一只支阅读 4,612评论 5 9