题目
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
输入: nums = [3,2,3] 输出: [3]
题解
第一种
我们先声明一个变量l,用于记录数组的长度,如果数组长度小于2,直接返回原数组nums,因为数组长度小于2,那么唯一的元素就是主要元素,不需要进行统计,然后我们在定义一个变量n,表示一个阈值,它等于数组长度的1/3,因为一个元素的出现次数超过了这个阈值,就认为它是数组中的主要元素,接下来我们在定义变量i和result,分别表示循环变量和结果数组,变量numsMap是一个空对象,用于记录数组中每个元素出现的次数,我们使用while循环进行循环,循环条件是i小于数组长度并且结果数组result的长度小于2,在循环中我们首先将nums[i]作为key,将numsMap中对应的value加1,表示这个元素又出现了一次,接下来判断这个元素是否出现次数超过了阈值n,并且是否已经存在于结果数组result中,如果是,则将这个元素加入结果数组result中,循环变量i自增1,进入下一轮循环,最后我们将result数组返回出去即可
var majorityElement = function(nums) { let l = nums.length; if(l < 2) return nums; let n = l/3; let i = 0; let result = []; let numsMap = {}; while(i < l && result.length < 2){ numsMap[nums[i]] = (numsMap[nums[i]] || 0) + 1 if(numsMap[nums[i]] > n && !result.includes(nums[i])){ result.push(nums[i]) } i++; } return result; };
第二种
我们在函数中先创建一个Map对象,用于存放数组中每个元素出现的次数,然后我们创建一个Set对象,用于存放出现次数超过1/3的元素,接下来我们遍历数组中的每个元素,对于每个元素进行判断,如果它已经被加入到Set对象中,就跳过不处理,否则我们就将该元素的出现次数加1,并判断是否超过了数组长度的1/3,如果是就将该元素加入到Set对象中,最后将Set对象中的元素转换为数组返回出去即可
var majorityElement = function(nums) { const map = new Map(); const res = new Set(); const len = nums.length; for(let i=0;i<len;i++){ const item = nums[i]; if(res.has(item)){ continue; } map.set(item,(map.get(item)||0)+1); if((map.get(item)>(len/3))){ res.add(item); } } return [...res]; };