查找并返回数组中出现频率最高的元素

Posted

技术标签:

【中文标题】查找并返回数组中出现频率最高的元素【英文标题】:Find and return the element which occurs most frequently in an array 【发布时间】:2019-08-15 02:25:28 【问题描述】:

我需要实现一个名为 findMode 的函数来查找数组的模式。假设数组仅包含整数。当函数被调用并且数组为空时,它返回 0。当函数被调用并且数组不为空时,它应该返回数组中出现频率最高的元素。如果一个数组包含多个模式,它应该返回模式的最小值。我需要创建一个中间数组,另一个数字数组来计算每个值出现的次数。这个数组应该使用数组的索引号来跟踪 b 中的数字被计算了多少次。

以下是我目前所拥有的:

import  print  from "....";

export let main = async () => 
    let input = [2, 1, 1, 2, 1, 0]
    print(mode(input))

;

export let findMode = (b: number[]): number => 
    let newArr: number[] = []; /** this is the new number array created to store count, this is the intermediate array */
    if (b.length === 0) 
        return 0;
    for (let i = 0; i < b.length; i++) 


;
main();

以下是预期/实际结果:

如果数组是 b[2,1,1,2,1,0],那么应该返回 1,如果我们打印我们创建的用于存储计数的数组,它应该打印 newArr[1,3,2]因为元素 0 出现了 1 次,元素 1 出现了 3 次,元素 2 出现了 2 次。我们的想法是从 0 作为输入数组中的元素到 0 作为中间数组中的索引。所以最后我们看到我们的最大出现次数(或中间数组中的最大元素)在索引 1 处为 3,因此模式为 1。

如果数组是 b[0,0,0,1,1,2,1,1] 那么应该返回 1。如果数组是 b[4,4,7,4,0,7] 那么应该返回 4。如果数组是 b[-4,-4,-1,3,5] 那么应该返回 -4。如果数组是 b[1,1,2,3,2] 则应返回 1,因为它是最小的模式。如果数组是 b[10,10,10,20,20,30] 那么应该返回 10。

【问题讨论】:

这是一个错字,已修复。 【参考方案1】:

这样的东西有用吗?

export let findMode = (b: number[]): number => 
    // we'll store the values in b and the number of times they occur here
    const counts: Array< value: number, count: number > = [];

    // it helps to check that b is defined before you check length, this avoids ReferenceErrors
    if (!b || !b.length) 
        return 0;
    

    for (let i = 0; i < b.length; i++) 
        const val = b[i];
        const count = counts.find(count => count.value === val);

        if (count) 
            count.count++;
         else 
            counts.push( value: val, count: 1 );
        
    

    // get the mode by sorting counts descending and grabbing the most occuring
    const mode = counts.sort((c1, c2) => c2.count - c1.count)[0];

    // and now if you *need* an intermediate array with the index mapped to the value and value mapped to the count:
    const largestNumber = counts.sort((c1, c2) => c2.value - c1.value)[0];
    // initialize an empty as long as the largest number
    let newArr = new Array(largestNumber);
    newArr = newArr.map((val, i) => 
        const count = counts.find(count => count.value === i);
        if (count) 
            return count.count;
         else 
            return 0; // 'i' occurs 0 times in 'b'
        
    );
;

【讨论】:

【参考方案2】:

您可以使用Array#reduce 方法通过附加对象来保持计数来实现结果。

export let findMode = (b: number[]): number => 
  // object for keeping count of each element
  // initially set `0` with 0 count (default value)
  let ref = 
    '0': 0
  ;

  return b.reduce((value, num) => 
    // define count as 0 if not defined 
    ref[num] = ref[num] || 0;

    // increment element count
    ref[num]++;
    // if number count is gretater than previous element count
    // then return current element
    if (ref[num] > ref[value]) 
      return num;
    // if counts are same then return the smallest value
     else if (ref[num] === ref[value]) 
      return num < value ? num : value;
    
    // else return the previous value
    return value;
    // set initial value as 0(default)
  , 0);
;

let findMode = b => 

  let ref = 
    '0': 0
  ;

  return b.reduce((value, num) => 
    ref[num] = ref[num] || 0;
    ref[num]++;
    if (ref[num] > ref[value]) 
      return num;
     else if (ref[num] === ref[value]) 
      return num < value ? num : value;
    
    return value;
  , 0);
;


[
  [2, 1, 1, 2, 1, 0],
  [1, 3, 2],
  [0, 0, 0, 1, 1, 2, 1, 1],
  [4, 4, 7, 4, 0, 7],
  [-4, -4, -1, 3, 5],
  [1, 1, 2, 3, 2],
  [10, 10, 10, 20, 20, 30]
].forEach(v => console.log(findMode(v)))

【讨论】:

以上是关于查找并返回数组中出现频率最高的元素的主要内容,如果未能解决你的问题,请参考以下文章

编写一个算法来查找数组中出现频率最高的元素。给出算法的时间复杂度

查找数组的最高频率以及具有该频率的所有元素

js查找数组中出现次数最多的元素

最大频率栈

最大频率栈

2021-11-12:前 K 个高频元素。给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。提示:1 <= nums.length <=