[leetcode]求众数[javascript]

https://leetcode-cn.com/problems/majority-element/

描述

给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在众数。

示例 1:

输入: [3,2,3]
输出: 3

示例 2:

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

分析

先说我自己的做法。
题目中已经说明了出现次数大于 ⌊ n/2 ⌋ ,我们循环的时候只需要循环到n/2 + 1。
用一个变量count保存出现次数,val表示众数,用一个对象保存需要判断的值,当相等时直接跳过此次循环;
每次循环用一个inCount保存当前值出现的次数,再嵌套一个循环判断是否相等,遇到相等就将inCount + 1;
里层循环结束之后,判断inCount与count的大小,如果inCount > count ,就赋值过去,并将val 改成当前遍历的值;
循环结束之后,直接return val

var majorityElement = function(nums) {
  let len = nums.length, count = 0, countobj = {}, val = 0
  for (let i = 0; i < parseInt(len / 2) + 1; i++) {
    // let inCount = 1
    if (countobj[nums[i]]) {
      continue
    }
    countobj[nums[i]] = 1
    for (let j = i + 1;j < len;j++) {
      if (nums[i] === nums[j]) {
        countobj[nums[i]]++
      }
    }
    if (countobj[nums[i]] > count) {
      count = countobj[nums[i]]
      val = nums[i]
    }
  }
  return val
}

后来看了评论,查了资料,其实简单点只需要一次循环就够了…

从第一个数开始count=1,遇到相同的就加1,遇到不同的就减1,减到0就重新换个数开始计数,总能找到最多的那个

这种方法叫做摩尔投票法 ,在任何数组中,出现次数大于该数组长度一半的值只能有一个。

摩尔投票法的基本思想很简单,在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。这样不断的删除直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半。如果只存在一种元素,那么这个元素则可能为目标元素。

var majorityElement = function(nums) {
  let len = nums.length, count = 1, val = nums[0]
  for (let i = 0; i < len; i++) {
    if (nums[i] === val) {
      count++
    } else {
      count--
    }
    if (count === 0) {
      val = nums[i]
      count = 1
    }
  }
  return val
}

参考资料

https://www.jianshu.com/p/c19bb428f57a

猜你喜欢

转载自blog.csdn.net/u010690493/article/details/85236783