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
}