下面我列出了一个问题,我遇到了一些麻烦。这个问题是一个简单的嵌套循环,远离O(n ^ 2)解决方案,但我需要它是O(n)。有什么想法应该解决这个问题吗?是否有可能形成两个方程式?
给定整数数组A,检查是否有两个索引i和j,使得A [j] = 2 * A [i]。例如,在数组(25,13,16,7,8)上,算法应该输出“true”(因为16 = 2 * 8),而在数组(25,17,44,24)上算法应该输出“假”。描述这个问题的算法,最坏情况下的运行时间优于O(n ^ 2),其中n是A的长度。
谢谢!
答案 0 :(得分:6)
这是使用哈希表的好地方。创建一个哈希表,并将数组中的每个数字输入哈希表。然后,再次遍历数组并检查每个i的哈希表中是否存在2 * A [i]。如果是这样,那么你知道这个属性存在一对索引。如果没有,你就知道不存在这样的一对。
在期望时,这需要时间O(n),因为对哈希表的n次操作需要预期的摊销O(1)时间。
希望这有帮助!
答案 1 :(得分:0)
templatetypedef建议使用哈希表是一个很好的建议。我想解释一下为什么。
这里的关键是要意识到你实际上是在集合中搜索某些值。你有在中搜索的一组数字(2 *输入数组中的每个值),以及你正在搜索的一组数字 (输入中的每个值)数组)。你的暴力天真案例只是直接在搜索阵列中查找值。您希望做的事情是将“搜索”集预先加载到比数组更快的查找(如哈希表),然后您可以从那里搜索。
您还可以通过不搜索A[i]
A[i]
奇怪的地方来进一步修剪结果;因为你知道如果A[i] = 2 * A[j]
是奇数,A[i]
永远不会成立。您还可以在初始化期间动态计算“搜索”数组中的最小值和最大值,并修剪该范围之外的所有A[i]
。
很难用大O形式表达,因为它取决于数据的性质,但你也可以计算最佳和最坏情况以及摊销的案例。
但是,正确选择哈希表大小(如果您的值范围很小,您可以简单地选择一个大于您的值范围的容量,其中哈希函数是值本身)可能实际上使修剪成本更高在某些情况下,您必须对其进行分析才能找到答案。