对二维数组进行二进制搜索以找到局部最大值?这个算法有什么问题?

Binary search over 2d array to find a local maximum? What's wrong with this algorithm?

这是在矩阵中寻找局部最大值(只有一个)的经典方法。

我的算法是:

由于这是对具有 n^2 个元素的 n x n 矩阵的二进制搜索,因此它应该需要 O(log(n^2)) = O(2*log(n)) = O(log(n))

我很确定这是不正确的,但我的错误在哪里?

此算法不能保证找到局部最大值。例如,考虑这样一种情况,您需要沿着一条蜿蜒的路径通过递增值矩阵才能到达峰值。如果该路径在象限之间来回交叉,您的算法将找不到它。

13  1  1  1  1
12  1  1  1  1
11  1  1  2  3
10  1  1  1  4
 9  8  7  6  5

或者,这是一个更简单的例子:

3  1  1  1  1
1  1  1  1  1
1  1  1  1  1
1  1  1  1  1
1  1  1  1  1

你从中间开始,你如何找到'3'?你的算法没有描述面对水平面时该怎么做。

考虑阅读 Find a peak element in a 2D array,其中描述了一种蛮力方法,以及一种时间复杂度为 O(rows * log(columns)) 的有效方法,在您的情况下 O(nlogn)

该算法基于二进制搜索,因此 logn 您的复杂度也有:

  1. 考虑中间列并找到其中的最大元素。
  2. 设mid列的index为‘mid’,mid中最大元素的值 列为“max”,最大元素位于“mat[max_index][mid]”。
  3. If max >= A[index][mid-1] & max >= A[index][pick+1], max是一个peak, return最大
  4. 如果 max < mat[max_index][mid-1],对矩阵的左半部分重复。
  5. 如果 max < mat[max_index][mid+1],重复矩阵的右半部分。

但是,您的算法不会适用于所有情况,并且可能无法找到局部最大值,因为您只查看当前中心的相邻元素,而这不会保证你会找到最大值(当然元素没有排序)。示例:

1 1 1 1 1
1 1 1 1 1
1 2 1 1 1
1 1 1 1 1
1 1 1 1 10

你从中心开始,你选错了子矩阵,你注定找不到局部最大值。