• 【算法】投票算法


    【适用场景】

    给定一个无序数组,有n个元素,找出其中的一个多数元素,多数元素出现的次数大于⌊ n/2 ⌋,注意数组中也可能不存在多数元素。
    注意:多数元素n>2,即投票的某个元素超过半数。

    【算法思路理解】

    采用的是 “支持票” 和 “反对票” 抵扣的思路。

    1.A表示支持票,B表示反对票
    采用A、B互相抵扣,最终剩余的类型就是投票结果(大于半数)
    image

    2.但实际用到的投票算法中,一般不止“支持票”、“反对票”两种形态。如下:

    • 大于半数的元素A,和其他元素两两抵扣后,剩余的元素一定是A
      image
    • 但,实际的投票算法中,初始我们是不A是“大于半数元素”,无法按照上图进行A 和 other抵扣。
      反而采用的是如下 按照 顺序逐个抵扣的方式:
      image
      其中C和D抵扣的这种方式,知会导致算法抵扣后最终剩余的“大于半数元素”A更多,不会导致“大于半数元素”统计错误。

    【注】:

    • 一定是“大于半数元素场景”;
    • 对于统计序列中数量最多元素、但是最大元素“不多于半数”场景不适用,如下:
      image

    【算法实现】

    需要记录两个信息:

    • candidate:记录抵扣后,剩余的元素
    • count:记录抵扣后,剩余的元素数量,初始为0

    【样例】:求众数
    给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
    你可以假设数组是非空的,并且给定的数组总是存在多数元素。

    示例:
    输入:[2,2,1,1,1,2,2]
    输出:2

    代码参考:

    public class MaxNumElement {
        public Integer getMaxNumElement(Integer[] array) {
            Integer element = -1;
            Integer count = 0;
    
            for (int i =0; i<array.length; i++) {
                if (count > 0) {
                    if (element != array[i]) {
                        count--;
                    } else {
                        count++;
                    }
                } else {
                    element = array[i];
                    count++;
                }
            }
    
            return element;
        }
    }
    

    【扩展】

    当然,也可不采用投票算法的方式:

    1. 序列排序。
    2. 中间元素一定是求的“大于半数元素”
  • 相关阅读:
    android intent 传递list或者对象
    MyEclipse快捷键大全
    keystore 介绍
    oracle存储过程学习---包的概念
    判断变量类型
    Android自定义控件之TextView
    Myeclipse SVN 修改用户名和密码
    关于Inflater
    windowsxp系统下SVN添加新用户
    【原创】python:open函数的使用方法
  • 原文地址:https://www.cnblogs.com/yickel/p/14825572.html
Copyright © 2020-2023  润新知