小白js硬啃leetcode算法-多数元素(数组简单-169)-4

69 阅读2分钟

题目

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

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

hash表

  • 解题思路:
    • 多位元素为出现次数大于n/2的元素,很容易想到遍历,之后将重复的元素进行计数,大于n/2的挑选出来
  • 复杂度
    • 时间复杂度:O(n)
    • 空间复杂度: O(1)
const majorityElement = function(nums) {
    const eObj = {}
    const level = nums.length /2
    nums.forEach(i=>{
        eObj[i] = eObj[i]? (eObj[i]+ 1 ):1
    })
    return  Object.entries( eObj ).filter( ( [k, v] )=> v > level )[0]
};

排序

  • 解题思路:
    • 如果一个元素个数大于n/2,那么这个元素经过排序之后位置一定在中间
  • 复杂度
    • 时间复杂度:O(nlogn)
    • 空间复杂度: O(logn)
const majorityElement = function(nums) {
	nums.sort( (a,b)=>{
    	if(a > b ){
        	return 1
        }
        if(a < b ){
        	return -1
        }
        return 0
    } )
    return  nums[ nums.length>>1 ]
};

摩尔投票法

  • 解题思路:
    • 求一个出现次数大于n/2的众数,可以使用摩尔投票法
    • 摩尔投票法:定义两个变量candidate(众数)、count(出现次数)。初始时candidate为第一个数字,count为0。遍历数组,当元素与candidate相同时,count+1,不同时count-1。当count为0时更换数字。最终candidate即为所求众数
    • 摩尔投票法原理
      • count为0时,表示有人反对,那一定会出现更换
      • 因为众数出现了n/2次,假设其他数字均为x,x均会支持自己反对众数,众数数目减去x数目还会剩余,可以推断出最终众数会将candidate变为自己
  • 复杂度
    • 时间复杂度:O(logn)
    • 空间复杂度: O(1)
const majorityElement = function(nums) {
 	let candidate =  null
 	let count= 0 
 	nums.forEach( n=>{
     	    if( count === 0 ){
         	candidate = n
     	     }
            count = count + (candidate === n?1:-1)
 	} )
        return candidate
};