数组中最常见的元素

时间:2016-06-04 08:51:56

标签: arrays

鉴于所有数字都在0到n-1的范围内,其中n是数组的长度。

如何在线性时间和恒定空间中解决这个问题?

4 个答案:

答案 0 :(得分:2)

您可以重复使用给定数组作为数字的计数器。只需遍历数组并增加相应的计数器。唯一的技巧是每次增加n,而不是一次:

for (int i = 0; i < n; ++i) {
    arr[arr[i]%n] += n;
}

在此循环元素之后,arr [i]将变为arr [i] + n * count [i],其中arr [i]

答案 1 :(得分:0)

这是实现这一目标的功能。但它不是你所要求的O(n),它是O(n ^ 2)。希望这个帮助

function getPopularElement(array) {
  var count = 1, tempCount;
  var popular = array[0];
  var temp = 0;

  for (var i = 0; i < (array.length - 1); i++) {
    temp = array[i];
    tempCount = 0;

    for (var j = 1; j < array.length; j++) {
      if (temp == array[j]) {
        tempCount++;
      }
    }

    if (tempCount > count) {
      popular = temp;
      count = tempCount;
    }
  }

  return popular;
}

答案 2 :(得分:0)

Heller的解决方案实际上与此类似:我们的想法是通过数组,并为每个元素增加一个计数器在数组中该数字的位置。通常,该位置还有另一个元素(Heller通过计算n的步长来保持信息)但我们可以递归和就地解析这些元素。这是每个元素最多完成一次的线性过程,因为不再有链(试图增加位置上的计数,找到新元素)而不是整个数组的长度(即单个置换周期)和一次处理一个元素,可以在主循环中跳过它,使其整体O(n)诀窍是减少计数器

//input: arr
//output: most frequent element, number of occurrences
n <- arr.length
for i = 0..n-1
    val <- arr[i]
    if val < 0
        // this element has already been processed
        continue
    // set counter at i to zero (-1)
    arr[i] <- -1
    // resolve the chain
    do
        idx <- val
        val <- arr[idx]
        if val < 0
            // arrived at a counter, end of chain
            // increase the counter by one (-1)
            arr[idx] <- arr[idx] - 1
            break
        }
        // otherwise continue the chain with val
        // and initialise the counter at idx to one (-2)
        arr[idx] <- -2

// find the most common element
idx <- 0
for i = 1..n-1
    // smaller value means larger counter
    if arr[i] < arr[idx]
        idx <- i

// [the most frequent element, number of occurrences]
output [idx, -(arr[idx] + 1)] // arr[i] = -1 - #occurrences

这个解决方案也可以很好地处理非常大的数组,其中Heller的解决方案中最大可能的计数器(n*n-1)溢出了底层整数(对于32位整数,这个数组的长度超过65535个元素! )

答案 3 :(得分:0)

让我们假设数组如下:

int arr[] = {10, 20, 10, 20, 30, 20, 20,40,40,50,15,15,15};

int max =0;
int result = 0;
Map<Integer,Integer> map = new HashMap<>();
    
for (int i = 0; i < arr.length; i++) {
    if ( map.containsKey(arr[i])) 
        map.put(arr[i], map.get(arr[i]) +1);
    else
        map.put(arr[i], 1);
    int key = map.keySet().iterator().next();
    if (map.get(key) > max) {
        max = map.get(key) ;
        result = key;
    }
}
System.out.println(result);

说明:

在上面的代码中,我采用了HashMap将元素存储在键中,并将元素的重复作为值。 我们已经初始化了变量max = 0(max是重复元素的最大数量) 在遍历元素的同时,我们还获得了键的最大数量。

result变量返回大多数重复的键。