在采访中我被问到了这个问题。我无法解决这个问题。我想知道是否有人知道如何解决它:
如果我有一个很长的整数列表,则返回频率方面排在前2位的整数。
e.g。 [1, 2, 3, 1, 4, 5, 6, 7, 8, 6, 1, 8, 8]
返回[1,8]
谢谢。
答案 0 :(得分:3)
遍历列表并使用值和计数创建最大堆。
如何保持跟踪肯定存在挑战。考虑一个快速解决方案(通常在采访中就是这种情况),我可能会保留一个字典来跟踪我是否为数组/列表中的任何给定int创建了一个对象,如果是这样,那么它是当前的索引。堆。如果是这样,那么我将获得该对象,更新它的计数器并在最大堆中涓流。
我可能会有一个包含数据的类,例如:
public class MyData
{
private readonly int _key;
public MyData(int key)
{
_key = key;
Count = 0;
}
public int GetKey()
{
return _key;
}
public int Count { get; set; }
}
我将有一个这样的结构(其中元组包含对象及其在堆数组中的索引(我将用于堆的数组实现)
var elementsInHeap = new Dictionary<int, Tuple<MyData, int>>();
当循环输入列表时,检查该字典中是否有该int的任何条目,如果是,则获取该值,获取对象,增加计数器,然后在堆中进行逐步处理。对于堆,您可以使用MyData对象,当使用向上或向下滴流时使用计数器值。如果没有,创建一个新的MyData对象,让它根据它的计数器在最大堆中涓涓细流,完成时将它添加到字典中,并在元组中使用它的索引。
希望这有帮助,我相信那里有一个更聪明的解决方案。希望有人会帮助我们。
答案 1 :(得分:1)
我认为建议构建堆或对数组进行排序的答案具有O(n log n)复杂度。
首先构建一个哈希映射,其中键是数组的(不同)元素,值是它们的频率。该地图可以在O(n)中轻松构建。
然后找到地图中条目的最大值和第二个最大值。这也可以通过仅迭代映射条目一次在O(n)中轻松完成。即使你决定迭代两次(找到一个最大值,删除它并找到下一个最大值),你的复杂性仍然是O(n)。
答案 2 :(得分:0)
如果您知道数字范围(最大和最小元素),您可以在数组的一个循环中使用数组和计数频率,
你也可以使用堆快速构造算法O(n)并且只提取最多2次,
或使用哈希(如果您能够在访谈期间实施)