【问题标题】:Location of the saddle point鞍点位置
【发布时间】:2018-02-23 19:33:17
【问题描述】:

我有以下问题

假设我们有一个 9*8 的矩阵

如果在某个位置,则称矩阵具有“鞍点” 是其行中的最小值和列中的最大值。 在 symbols 中,a[i][j] 是一个鞍点,如果

 a[i][j]=min a[i][k]  ==max a[k][k]
             1<=k<=8      1<=k<=9

请帮我找到鞍点的计算机位置。

【问题讨论】:

  • 到目前为止你取得了什么成就?你哪里有问题?

标签: algorithm


【解决方案1】:

给定 MxN 矩阵,这是O(MN),这是最优的。

INIT rowMin = [ +Infinify ] xM
INIT colMax = [ -Infinity ] xN

FOR r = 1..M
  FOR c = 1..N
    rowMin[r] = MIN(rowMin[r], mat[r][c])
    colMax[c] = MAX(colMax[c], mat[r][c])

FOR r = 1..M
  FOR c = 1..N
    IF mat[r][c] == rowMin[r] == colMax[c]
       DECLARE saddlePoint(r, c)

为什么这是最优的?

因为有 MxN 个值,并且每个值都需要查看,所以为了确定您的答案(即不是概率),下限为 O(MN)

可以进一步优化吗?

你可以稍微优化一下。它仍然是O(MN),但不是找到最大/最小,而是找到它们的索引。这可以使第二阶段 O(M) 在最佳情况下(即当行/列中存在唯一的最小值/最大值时)。

请注意,在最坏的情况下,存在O(MN) 鞍点:即数组中的数字都相等。

【讨论】:

  • 我认为您在代码的第 2 行有一个错误(-Infinity?);即使我没有得到 ... x M 或 ... x N 符号
  • 我很确定 O(MN) 不是最优的。
  • @unreason:是的,错误。固定的。该符号是[1,1,1] = [1]x3 的缩写
  • @Nick:有O(MN) 值。不看每个人,你怎么能回答这个问题?
  • 对不起,你是对的 - 我误读为大于数组中的值的数量,不知何故。不过,您的最后一个循环不是最理想的 - 请参阅我对最后一部分 O(min(m, n)) 解决方案的回答。我看到你已经提到了这种可能性,但实现起来也不难。
【解决方案2】:

天真的解决方案是:

  • 找出所有行的最小值
  • 查找列的最大值
  • 看看有没有在同一个位置

【讨论】:

    【解决方案3】:

    简而言之:

    1. 遍历每一行,找到该行中最小值的列号。
    2. 遍历每一列,找出该列中最大值所在的行号。
    3. 遍历rows-mins 或column-maxes,检查对应的单元格是否也是另一个数组中的最大值。

    这是 Python 中的一个实现:

    def find_saddle_points(a):
      """Finds saddle points in a, a 2 dimensional array.
    
      Args:
        a: A 2 dimensional array in row-major (y, x) order.
      Returns:
        A list of (x, y) location of the saddle points.
      """
      # Holds a (value, column) tuple of the min value and its column for each row.
      row_mins = [min((a[row][col], col) for col in range(len(a[row]))) for row in range(len(a))]
      # Holds a (value, row) tuple of the max value and its row for each column.
      col_maxes = [max((a[row][col], row) for row in range(len(a))) for col in range(len(a[0]))]
    
      ret = []
      for row, (row_min, col) in enumerate(row_mins):
        if col_maxes[col][1] == row:
          ret.append((row, col))
      return ret
    

    【讨论】:

    • 我不懂python,但你说你的第二阶段是O(min(M,N)),但你声称返回所有鞍点。在最坏的情况下,每个点都是一个鞍点,所以第二阶段必须是O(MN)。你怎么解释这个? (顺便说一句,+1)
    • 你说的很对 - 每行(或每列,如果你反转最后一个循环)最多会返回一个鞍点。这可能是也可能不是一个重要问题,具体取决于应用程序,因为在常见情况下(没有许多重复值的数组),只能有一个鞍点。
    【解决方案4】:

    你自己回答了这个问题:

    找到每一行中最小元素的位置, 求每列最大元素的位置,

    出现在两个列表中的任何位置都是鞍点

    还有改进的余地 - 但基本上就是这样

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 2021-12-20
      • 2017-04-16
      • 1970-01-01
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      相关资源
      最近更新 更多