【问题标题】:Given a List of Integers, find the most frequently occurring integer in the list给定一个整数列表,找出列表中出现频率最高的整数
【发布时间】:2019-08-31 08:16:16
【问题描述】:

我最近在一次采访中提出了这个问题。给定一个整数列表,找出列表中出现频率最高的整数并返回一个数组。我能够回答,但其中一个测试用例让我失望了。

我不知道应该使用哪种排序方法对数组进行排序以获得最常见的整数并返回数组中包含最常见整数的所有项目。

const arr = [1,1,2,3,3,3,3,4,5,5,10]; // return 3 

const mostCommon = (arr) => {
 if (arr.length < 1 ) {
     return null;
 }
    const map = {};
    let mostFrequentNum = arr[0];
    for (let i = 0; i < arr.length; i++) {
      let currentNum = arr[i];
        !map[currentNum] ? map[currentNum] = 1 : ++map[currentNum];
        // 1. Current has higher count than known max
        if(map[currentNum] > map[mostFrequentNum]) {
        mostFrequentNum = currentNum;
       }
    }
    return mostFrequentNum;
};
mostCommon(arr); // return 3

/* confused how to implement test case below */
// const arr = [5, 99, 3994813, 99, -32, 43, 99, 3994813, 3994813]; 
// return [ 99, 3994813 ]

【问题讨论】:

  • 你肯定不想从if 声明里面去return;您将跳过原始数组的一部分。
  • 最简单的解决方案:对数组进行排序后,在第一次迭代中找到最频繁出现的数字的次数。然后在第二次迭代中返回所有出现多次的数字。
  • 您的问题令人困惑:您使用“整数”一词,单数,但随后您还说您想要一个具有多个值的数组,以防出现平局。是哪个?
  • @Pointy 无用和愚蠢的面试问题措辞不佳的情况并不少见 :-)
  • @pointy 谢谢。我并不是要在 if 语句中返回。我纠正了它。我认为面试官的意思是询问第一个测试用例中最常见的整数以及包含第二个测试用例中最常见整数的数组中的所有 num 集,我也对它的措辞感到困惑。感谢您的帮助。

标签: javascript arrays


【解决方案1】:

只需像你正在做的那样累积计数,然后完成后通过并找到最大的计数。

    const arr = [1,1,2,3,3,3,3,4,5,5,10]; 
    
    const mostCommon = (arr) => {
        const map = {};
        for (currentNum of arr) {
          !map[currentNum] ? map[currentNum] = 1 : ++map[currentNum];
        }
        let result = Object.keys(map).reduce((r, n) => {
          if (map[n] > r.c) {
            r.c = map[n];
            r.n = n;
          }
          return r;
        }, { c: -1 });
        return result.n;
    };
    console.log(mostCommon(arr));

    console.log(mostCommon([5, 99, 3994813, 99, -32, 43, 99, 3994813, 3994813]));

.reduce() 进程保留一个对象,该对象包含原始数组中的数字字段及其计数。

您的问题使用“整数”单数,但您的示例表明您希望 list 值与最大计数相关联。为此,您需要修改上述内容以使用列表而不是简单的标量来维护 .reduce() 累加器:

    const arr = [1,1,2,3,3,3,3,4,5,5,10]; 
    
    const mostCommon = (arr) => {
        const map = {};
        for (currentNum of arr) {
          !map[currentNum] ? map[currentNum] = 1 : ++map[currentNum];
        }
        let result = Object.entries(map).reduce((r, [n, c]) => {
          if (c > r.max) r.max = c;
          r[c] ? r[c].push(n) : r[c] = [n];
          return r;
        }, { max: -1 });
        return result[result.max];
    };
    console.log(mostCommon(arr));

    console.log(mostCommon([5, 99, 3994813, 99, -32, 43, 99, 3994813, 3994813]));

【讨论】:

  • 谢谢。这是一个出色的实现,我可以真正从中学习。
【解决方案2】:

我只有一种解决方案;)

const arr = [1,1,2,3,3,3,3,4,5,5,10];

var
  counting  = {},
  most_Freq = arr[0]
  ;

arr.forEach( x=>{ counting[x] = (counting[x] || 0)+1; });

most_Freq = Object.keys(counting).reduce((a, b) => counting[a] > counting[b] ? a : b);

console.log ( 'most frequent is ', most_Freq )

【讨论】:

    【解决方案3】:

    使用Array.reduce() 创建带有频率的数字地图。

    使用Math.max()Map.values()获取最高频率。

    将Map转换为条目数组([key, value]),过滤掉频率低于最高频率的项,映射到数字列表。

    const arr = [1, 1, 2, 3, 3, 3, 3, 4, 5, 5, 10];
    
    const mostCommon = arr => {
      const freqMap = arr.reduce((r, n) => r.set(n, (r.get(n) || 0) + 1), new Map); // create a Map of number by frequency
      
      const highestFreq = Math.max(...freqMap.values()); // get the highest frequency number
      
      return Array.from(freqMap) // convert the Map to an array of entries
        .filter(([, v]) => v === highestFreq) // filter lower frequency items
        .map(([k]) => k); // convert back to an array of numbers
    }
    
    console.log(mostCommon(arr));
    
    console.log(mostCommon([5, 99, 3994813, 99, -32, 43, 99, 3994813, 3994813]));

    【讨论】:

      猜你喜欢
      • 2018-04-04
      • 1970-01-01
      • 2014-12-28
      • 1970-01-01
      • 2012-02-12
      • 2019-04-03
      • 2017-07-18
      • 2019-01-14
      • 1970-01-01
      相关资源
      最近更新 更多