如何在小于O(n)的数组中找到最多出现的数字?

时间:2015-03-10 03:11:06

标签: javascript arrays regex algorithm

我一直在研究一些Coding Katas来改进我的编程。我的问题是如何使用 小于 O(n)解决此问题。我的第一个想法是使用正则表达式,但我遇到了一些问题,如下所述。

问题定义

  

使用JavaScript语言,使用SimpleMode(arr)函数   存储在arr中的数字数组,并返回显示的数字   最常见的(模式)。例如:如果arr包含[10,4,5,2,   4]输出应为4.如果有多个模式返回   首先出现在阵列中的那个(即[5,10,10,6,5]应该   返回5,因为它首先出现)。如果没有模式返回-1。   该数组不会为空。

O(n)解决方案

以下是我能够提出的O(n)解决方案:



function simpleMode(set) {
  var counter = {};

  var most = set.reduce(function(most, value) {
    if (!counter[value]) {
      counter[value] = 0;
    }

    counter[value]++;

    if (!counter[most] || counter[value] > counter[most]) {
      most = value;
    }

    return most;

  }, -1);

  return (counter[most] === 1 ? -1 : most);
};

console.log(simpleMode([5, 2, 5, 2, 3, 1]));

<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
&#13;
&#13;
&#13;

到目前为止

正则表达式解决方案:

这个解决方案的问题在于它不能满足返回最早出现的值的要求。同样,我觉得使用sort有点作弊,但它应该仍然小于O(n)。

&#13;
&#13;
function simpleMode(set) {
  var values = set.sort().join('')
  var regex = new RegExp(/(\d)\1+/g);
  var matches = regex.exec(values);

  return (matches ? matches[1] : -1);
}

console.log(simpleMode([5, 2, 5, 2, 3, 1]));
&#13;
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
&#13;
&#13;
&#13;

摘要

  • 如何用小于O(n)来解决这个问题?
  • 如何修复正则表达式解决方案?

1 个答案:

答案 0 :(得分:4)

这样的算法是不可能的。假设任何算法查看的数组少于n / 2个元素。然后,如果未查看的元素都是相同的,它们将是最常见的值。

所以找到最常见元素的任何算法必须始终查看数组的n / 2个元素,因此其时间复杂度必须至少为O(n)。