我正在使用Scala实现一个算法,用于从单独的数组l1和l2中查找值x1和x2,使得x1 + x2 = t,其中t是某个目标值。
算法1逐个遍历l1和l2并检查x1 + x2 = t。在O(n ^ 2)中运行。 算法2对l2进行排序,然后对l1中的每个项目执行二进制搜索。据说在O(nlogn)中运行,但没有。为什么它比算法1运行得慢?
请注意,这是课程作业,我只是寻找线索。
算法1:
def hasPairSlow(l1: List[Int], l2: List[Int], target: Int): Option[Pair[Int, Int]] = {
l1 foreach { i =>
l2 foreach { j => if (i+j == target) return Some(i -> j) }
}
None
}
算法2:
def hasPair(l1: List[Int], l2: List[Int], target: Int): Option[Pair[Int, Int]] = {
val s2 = l2.sorted
l1 foreach { i =>
val p = checkPair(i, s2, target)
if (p.isDefined) return Some(i, p.get)
}
None
}
private def checkPair(x: Int, l: List[Int], target: Int): Option[Int] = {
val mid = l.length / 2
if (mid == 0) { // Length == 1
if (l.head + x == target) Some(l.head) else None
} else {
val candinate = l(mid)
if (candinate + x == target) Some(candinate)
else {
val s = l.splitAt(mid)
if (candinate + x > target) {
checkPair(x, s._1, target)
}
else /* candinate + x < target */ {
checkPair(x, s._2, target)
}
}
}
答案 0 :(得分:2)
val s = l.splitAt(mid)
splitAt
函数遍历整个列表(如列表中的随机访问一样),因此您的第二个算法不会更好。由于元素访问和列表拆分所涉及的开销,情况更糟。
答案 1 :(得分:1)