算法题解-多数元素2

119 阅读2分钟

题目

给定一个大小为 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];
};

坚持努力,无惧未来!