【问题标题】:x+y-z between -1 and 1 [closed]x+y-z 在 -1 和 1 之间 [关闭]
【发布时间】:2012-10-03 15:55:18
【问题描述】:

[a_1 a_2 ... a_n] 成为[1,10n] 范围内的不同 整数列表。给出一个算法,如果存在三个不同的元素 x,y,z,则返回 true,使得 -1 <= x+y-z <= 1,否则返回 false

蛮力算法(检查x+y-z 的所有可能组合,及时运行O(n^3)。有更高效的算法吗?

【问题讨论】:

  • 您在尝试实现此功能时是否遇到特定问题,或者您只是逐字发布作业问题?
  • 不,我在实施蛮力算法方面没有问题。我想知道是否有更有效的算法。
  • 为什么要投反对票? :\
  • @amit:这是一个算法问题,被表述为一般的编程问题,因此很难看出用户在寻找什么。此外,人们倾向于关闭他们认为无法回答的问题。过于本地化是目前的主要原因,我不同意,但可以看到它们来自哪里。
  • @Guvante SO中有很多这样的问题。 OP提出了一个具体问题,并展示了他的努力(蛮力解决方案)。可以要求更好的方法,或者“怎么做?”在表现出一些努力之后。此外 - 如果某些事情“无法回答”(在这种情况下,如果没有更好的解决方案) - 一个好的答案将是解释原因(很多时候这是人们询问 NP-Hard 问题的情况,例如)

标签: algorithm list language-agnostic integer


【解决方案1】:

是的,有。这是使用O(n) 额外空间的O(n^2) 最坏情况算法。

这个想法是检查所有可能的对(而不是三元组),并迭代地标记您已经看到的元素,并将每对的总和与它们进行比较。
对于每一对,检查它的总和是否有匹配的元素,该元素恰好是总和 (x+y-z == 0) 或者如果添加 1 (x+y+1-z == 0 -> x+y-z = -1) 可以得到的元素,或者如果减少 1 (@ 987654325@)

伪代码:

mark = new boolean[10n]; //all initialized to false
sort arr //O(nlogn)
for each i in n,1: (reverse order)
   for each j in 1,i-1:
      //neglected range check, make sure it is done
      if (mark[arr[i]+arr[j]] || mark[arr[i]+arr[j]+1] || mark[arr[i]+arr[j]-1]):
          return true
      mark[arr[i]] = true
return false

请注意,我们将 in 迭代到 1,因为 z > xz > y - 我们要确保我们正在检查所有包含已在列表中的元素的对(如果它存在)

正确性证明:
如果有解决方案x+y-z = 0 - 那么z > xz > y (所有元素都是正不同整数)。
不失一般性,我们假设x > y。因此,当在外循环中迭代arr[i]=x 时,会有一些j<i 使得arr[j]=y。另外,因为z>x - mark[z] == true - 因为我们在之前迭代它时标记了它。
因此:算法将找到mark[arr[x] + arr[y]] == true,并产生true
+-1 案例的类似证明。

如果算法结果为真,则它发现其中一个条件为真。假设它是mark[arr[i] + arr[j]](其他情况的证明将类似)。
所以,我们发现了 mark[arr[i] + arr[j]] == true - 所以我们插入了它,因为有一些元素 z 使得 z = arr[i] + arr[j],并且算法对于这种情况是正确的。

【讨论】:

  • 不错的算法!有趣的是是否存在O(n log n) 算法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 2018-08-12
  • 2021-09-13
  • 1970-01-01
  • 2017-03-02
相关资源
最近更新 更多