在二维数组中找到局部最小值

时间:2012-04-08 13:48:10

标签: algorithm

给定一个N-by-N阵列a N 2 不同的整数,设计一个O(N)算法来找到一个局部最小值:一对索引 i j 这样:

  • a[i][j] < a[i+1][j]
  • a[i][j] < a[i-1][j]
  • a[i][j] < a[i][j+1]
  • a[i][j] < a[i][j-1]

我在一个在线算法手册Introduction to Programming in Java, chapter 4.2: Sorting and Searching中找到了这个问题。

类似于问题35(同一页):

  • 给定一个N个实数的数组,写一个静态方法,以对数时间找到一个局部最小值(索引 i ,使a[i-1] < a[i] < a[i+1])。

它有一些基于二进制搜索的解决方案,我无法找到。

3 个答案:

答案 0 :(得分:7)

书籍Algorithms by Robert Sedgewick and Kevin Wayne. (See "Creative problems" section, problem 19)的网络版中提到了同样的问题。

作者在that link中提出的问题的提示是:

找到行N / 2中的最小值,检查列中的邻居p和q,如果p或q小于那么在那一半重复。

更好的方法是: 找到行N / 2中的最小值,检查其列中的所有条目,如果我们在列中获得较小的条目,则在较小列条目所属的行中重复。

例如。 对于下面的数组,N = 5:

1  12  3   1  -23  
7   9  8   5   6
4   5  6  -1  77
7   0  35 -2  -4
6  83  1   7  -6

第1步:中间一行是[4 5 6 -1 77]。即。第3行。

第2步:当前行的最小条目为-1

步骤3:最小条目的列邻居(即-1)为5-2-2是最小邻居。它在第4排。

继续执行步骤2-3,直至我们获得local min

修改

例如@anuja的评论中提到的 (主要问题是n-by-n数组。这个输入是3乘4的数组,但我们可以使用它)

1 2 3  4 
5 1 6 -1
7 3 4 -2

第1步:中间行为[5 1 6 -1]。即。第2行。

enter image description here

第2步:当前行的最小条目为-1

enter image description here

步骤3:最小条目的列邻居(即-1)为4-2-2是最小列邻居。它排在第3行。

enter image description here

迭代到步骤2:-2在其行中最小,在其列邻居中最小。所以我们以-2作为局部最小值的输出结束。

enter image description here

答案 1 :(得分:5)

更新:这个答案假设边缘不是局部最小值,因为它们不是由原始问题陈述中的四个比较定义的。在这种情况下,这个答案是正确的(这是不可能的)。如果你重新定义边缘可以是局部最小值的问题,那么每个矩阵至少包含一个局部最小值 - 因此你可以使用分而治之的方法。

如果边缘单元格不能是局部最小值:

如上所述,问题无法解决。 N-by-N阵列仅需要O(N ^ 2)时间来读取元素。由于矩阵中可能存在单个局部最小“隐藏”,因此这是必要的。

如果你想要一个O(N ^ 2)算法,而不是简单地走每个元素并将它与它的4个邻居进行比较需要花费O(N ^ 2)时间。

你要么误解了面试问题(而且还有更多的问题),或者这只是一个简单的编码练习。

<强>证明

1. Construct a NxN matrix such that each cell has the value M[i,j] = N*i + j.
2. Select a random x,y (1 < x < N and 1 < y < N) and assign M[x,y] = -1

该矩阵恰好具有一个局部最小值(M [x,y]),并且其位置独立其他单元格中的值。因此,其他单元提供关于其位置的无信息,因此不可能有任何系统搜索优于预期(N ^ 2/2)单元搜索= O(N)的任何系统^ 2)。

(换句话说,除了最小值的M [x,y] = -1之外,你也可以搜索几乎所有的零矩阵M [i,j] = 0。)

此证明取决于能否在步骤1中构造一个没有局部最小值的矩阵。如果边缘单元可能是局部最小值,则每个矩阵必须有一个,并且此证明不再成立。< / p>

答案 2 :(得分:2)

访问随机单元格。如果它的四个neigbors中的任何一个具有较小的值:去那个单元格。如果没有一个较小的东西,那么你当地的最低限度。如果可以使用具有相等值的单元格,则会更难避免循环。

更新

我们可以选择最小的neigbor而不是访问一个neigbor。

最困难的拓扑似乎是两个“同心”螺旋的情况,其中一个起螺旋堤的作用。在最坏的情况下,这仍然需要大约N / 2步。 (N =细胞数。)