我正在研究一种算法来查找数字数组中的第一个重复元素。我理解这样做我应该对我的数组进行排序(在O(nlogn)中使用合并排序),然后在元素(O(logn))上执行二进制搜索时遍历数组。所以我的算法的总运行时间是O(nlogn)+ O(logn)= O(nlogn)。我的问题是我错过了O(nlog²n)。我不明白为什么日志会被平方。
问题陈述:
你会收到一个整数列表,一次一个,a1,a2,......我想要 你第一次发现ai出现了 先前,即找到最小的i,使得所有a1,a2,...,ai-1 对于某些
1≤j<i
来说是不同的但是ai = aj。描述一个O(i log2 i)时间 算法找到最小的i。 (以递归方式提供算法 使用Master Theorem表单并显示其运行时间。 )
答案 0 :(得分:3)
按如下方式使用BST:
- 初始化二进制搜索树
- 对于出现的每个新元素,将其插入树中并更新树
- 每当您找到BST中已存在的元素时,=&gt;你找到了最小的 i 索引
醇>
在插入第k个元素时,更新树的复杂性为O(kLogk)。
答案 1 :(得分:3)
您的算法不正确,因为它的运行速度低于实际问题的要求。
问题明确要求在O(i logi)
时间内运行,其中i
是第一个欺骗。如果你在数字流完成时你的algorirthm,你太慢了(流也可能是无限的!)如果你为每个新数字重复算法,它将运行得太慢(1log1 + 2log2 + 3log3 + ... + ilogi
不在O(ilogi)
)。
您可以通过维护一个集合(基于self balancing BST),以及何时出现新元素来实现:
check if it is in the set
if it is:
abort - found the first dupe
otherwise:
add it.
另请注意,要求(如您所说)是O(i log_2i)
,而不是O(i*log^2(i))
答案 2 :(得分:2)
查找重复元素只需要O(n log n)时间。
对数组进行排序后,重复的元素将彼此相邻;您不需要执行二进制搜索。
编辑以回应编辑过的问题:
如果您需要在线流式算法而不是批处理任务,那么您可以使用已遇到的元素的平衡搜索树。这应该在第一个i元素上提供O(i log i)性能。