algorithm - 鞍背搜索起点

标签 algorithm sorting haskell

我目前正在阅读 Richard Bird 和 Jeremy Gibbons 合着的 Algorithm Design with HaskellSaddleback search算法在第四章中给出了二分查找后,给出的动机问题是:

给定 f:N x N -> N 在两个参数中都严格递增,并且值 t 找到所有对 (x,y) 这样 f(x,y)=t

第一个定义由 search f t =[(x,y) | x ← [0..t],y ← [0..t],t == f(x,y)],从左下角的原点开始向右上角搜索角,(索引从下到上,从左到右递增),然后本书继续进行改进。

第二个定义由 search f t =[(x,y) | x ← [0..t], y ← [t,t −1..0],t == f(x, y)], 书中引用了这个定义

“第一个改进是从左上角开始,而不是从左下角开始”,然后本书继续进行,直到它变成 Theta(m+n) 对于维度为 n x m.

最终的算法是这样的

search f t = searchIn (0,t)
 where searchIn (x, y) | x>t ∨ y<0 =[]
 | z<t = searchIn (x+1, y)
 | z == t = (x, y):searchIn (x+1, y−1)
 | z>t = searchIn (x,y−1)
  where z = f(x,y)

为什么会这样?从原点(0,0)开始有什么问题?,还有 为什么 x 坐标增加而 y 坐标减少,反之亦然(我在 leetCode 上看到 x 减少,y 增加),为什么不让两个坐标都朝增加的方向移动?

最佳答案

问题的典型输入如下所示:

Typical input pattern. A curvy line begins in the top left and ends in the bottom right, separating a pure white patch from a pure black patch. Some grey spots appear along the curve.

黑色像素表示大于 t 的值,白色较小,灰色等于。我们的目标是找到所有的灰色点。理想情况下,要进行此搜索,我们只想沿着黑色和白色之间的边界行走。唯一的问题是我们不知道边界从哪里开始,所以我们需要搜索甚至知道在哪里搜索。如果我们从左下角开始,我们将不得不这样做:

The previous curve is shown again, with a new red curve added. The red curve begins with a straight line from the bottom left corner, extending vertically to the previous curve's start in the top left, then following the previous curve towards the bottom right.

第一步是找到边界,我们可以从左下角向上扫描,直到找到它。但是……我们必须掉头!搜索的其余部分,我们继续向下和向右。所以我们必须把我们的搜索分成两个阶段,一个是找到边界,另一个是跟随它。但是,如果您从左上角开始...

The first curve appears a third time, again with a red curve added. This time, the red curve begins in the top left corner, extending vertically downward in a straight line until it reaches the previous curve, then mimicking the previous curve as it meanders toward the bottom right.

这一次,我们不必掉头,这意味着我们可以重用我们用于跟踪其余边界以首先找到边界的相同代码!

这回答了“为什么不从原点开始”。另一个问题,“为什么不在一个方向上增加而在另一个方向上减少”,好吧......你可以。这是一个几乎相同的问题,几乎相同的算法将解决它。

关于algorithm - 鞍背搜索起点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68854526/

相关文章:

algorithm - 为什么在平均情况下链排序 O(n sqrt n)?

performance - 当没有 HasCallStack 时,errorWithoutStackTrace 会比 error 更快吗?

algorithm - 通过有效地找到最后使用的元素来保持缓存( map )小

c++ - minimax算法中的maximum-edge是什么?

algorithm - 查找每个商店的间隔

sorting - lisp 中的非破坏性排序?

php - 在 mysql 中使用 WHERE 和 IN 时数组的排序问题

haskell - 管道管道的执行时间很奇怪

haskell - 很难理解如何使用 nubBy

python - 神经网络反向传播不训练