鉴于所有数字都在0到n-1的范围内,其中n是数组的长度。
如何在线性时间和恒定空间中解决这个问题?
答案 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变量返回大多数重复的键。