数组中出现次数超过一半的数字:摩尔投票法

遇到一个很有意思的题目,学到了一个新的算法【摩尔投票法】,记录一下~
题目是这样的:

  • 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
    你可以假设数组是非空的,并且给定的数组总是存在多数元素。
    示例:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

限制:

1 <= 数组长度 <= 50000

本来我的想法是对数组进行排序,中间的那位数字一定是要找的元素,但是提交后发现占用的时间和内存都非常大,发现别人使用的都是【摩尔投票法】,且时间复杂度为O(n),空间复杂度为O(1)。

摩尔投票法的思路是这样的:
利用抵消原理,如果一个元素的占比超过一半,那它出现的次数就可以抵消掉其他元素出现次数。
先将第一个数记录为临时答案,记录为res,此时这个答案出现的次数为1,记录为count。然后从第一位开始,循环数组,如果在循环中遇到和res值相等的元素,出现次数加一,count++;如果当前循环到的元素和res不相等,抵消一次,count--;当count为0时,前面的元素已经全部抵消,将res修改为全部抵消后的第一个元素,count重新变为1。重复这个过程,直到结束循环,此时留下来的res,就是出现次数最多的那个元素。

代码实现:

function majorityElement(nums: number[]): number {
  let res = nums[0];
  let count = 1;
  for (let i = 1; i < nums.length; i++) {
    if (res == nums[i]) {
      count++;
    } else {
      count--;
    }
    if (count == 0) {
      res = nums[i];
      count = 1;
    }
  }
  return res;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容