我目前正在尝试验证,给定一个长度为 N 的未排序数组 A 和一个整数 k,是否存在一些出现 n/k 次或更多次的元素。
我对这个问题的想法是计算模式,然后将其与 n/k 进行比较。但是,我不知道如何快速计算这种模式。我的最终结果需要是 n log(k),但我真的不知道如何做到这一点。我能找到的最快的是n k...
我目前正在尝试验证,给定一个长度为 N 的未排序数组 A 和一个整数 k,是否存在一些出现 n/k 次或更多次的元素。
我对这个问题的想法是计算模式,然后将其与 n/k 进行比较。但是,我不知道如何快速计算这种模式。我的最终结果需要是 n log(k),但我真的不知道如何做到这一点。我能找到的最快的是n k...
使用哈希表计算每个值的频率:
uint[int] counts;
foreach(num; myArray) {
counts[num]++;
}
int mostFrequent;
uint maxCount = 0;
foreach(num, count; counts) {
if(count > maxCount) {
mostFrequent = num;
maxCount = count;
}
}
设置 m = n/k 向上取整。进行快速排序,但丢弃长度小于 m 的子列表。
像快速排序一样,你可能运气不好,反复选择接近末端的枢轴。但是,如果您随机选择枢轴,这发生的可能性很小。
递归将有 O(log(k)) 个级别,每个级别需要 O(n) 时间。
只需遍历数组并将计数保存在哈希/字典中(一旦找到 n/k 就返回 true,否则返回 false)将是 O(n)
编辑,类似于:
counts = {}
for n in numbers:
if ( counts.has_key( n ) ):
counts[ n ] += 1
else:
counts[ n ] = 1
if ( counts[ n ] >= n / k ):
return true
return false
在 F# .net 中为具有单一模式的数据集(整数)计算统计模式
let foundX (num: int, dList) = List.filter (fun x -> x = num) dList
let groupNum dList =
dList
|> (List.map (fun x -> foundX (x, dList)))
|> (List.maxBy (fun x -> x.Length))
let Mode (dList: int List) =
let x = groupNum dList
x.Head
//using Mode
let data = [1;1;1;1;1;1;1;1;2;2;3;3;3;1;4;4;4;4;4]
Mode data;;`
伪代码:
found = false
value = null
B = new hashtable
for (i =0, j = A[i]; i < |A| and !found; ++i, j=A[i])
if B contains key j
B[j] = B[j] + 1
if B[j] > |A|/k
found = true
value = j
endif
else
B[j] = 1
endif
end for
假设您的哈希表实现具有 O(1) 插入/查找,这应该是 O(n)