【问题标题】:what can be optimal solution for problem? [duplicate]什么可以是问题的最佳解决方案? [复制]
【发布时间】:2018-11-21 12:52:04
【问题描述】:

设一个数组:[6,9,2,4,1]

我需要查找输入数字是否有一对。
前任。输入 - 7
输出 - 是 (6+1 )

输入 - 16
输出 - 否(没有对加法是 16)

我知道运行 2 个循环的明显方法,但它具有时间复杂度 n^2 。有人可以帮我提供一些优化的解决方案吗?
编程语言:Java

我尝试了什么: 1) 排序数组
2)根据输入数将其分为2个子数组(输入/ 2)。
3) 第一个数组的内循环和第二个数组的外循环

这减少了迭代。

【问题讨论】:

  • 你可以用 1 个循环来完成,例如: foreach(var i in array) { if (array.contains( input-i)) { //combination found break; } }
  • 您可以排序和使用 2 个指针。时间复杂度为 O(n log(n)),空间为 O(1)。您还可以使用时间复杂度为 O(n) 且空间为 O(n) 的 HashMap。您可以用时间换取空间,反之亦然。
  • @Luc 这仍然是 O(n^2)
  • @Luc:array.Contains 需要查找包括循环在内的数据...
  • 1.初始化一个空的哈希集。 2. 运行循环并检查 if(hashset.contains(num - arr[i]){ return "Yes"} hashset.add(arr[i]) 3. End of loop return "No"

标签: algorithm sorting


【解决方案1】:

如果您的列表已排序,请考虑同样的问题。然后更容易确定列表中是否有一对总和为 Input。以下是您可以使用的算法的高级描述:

  1. 对数组进行排序
  2. 在最左边的元素上设置两个指针l,在最右边设置r
  3. 一次向内移动一个指针,使用类似于下面的 while 循环:

如下(伪代码):

l = 0
r = length(Input) - 1
while l < r:
    if (arr[l] + arr[r] == Input) return (arr[l], arr[r])
    else if (arr[l] + arr[r] < Input) l = l+1
    else r = r-1
return NULL

循环本身是线性的(O(n)),排序可以在O(n*log n)时间完成。因此整个算法的复杂度为O(n + n*log n) = O(n*log(n))

【讨论】:

    【解决方案2】:

    嵌套 for 循环是 O(n^2)。排序是 O(nlogn)。这种 O(n) 方法怎么样:

    1) 创建数组的散列集 2) 遍历数组一次,检查每个索引 i 是否 value-arr[i] 在集合中。

    例子:

    values = set(array) 
    for i in array:
         if 7 - i in values:
              return i, 7-i
    

    【讨论】: