简体   繁体   English

在 O(n) 中的已排序矩阵中查找小于目标的 # 个元素的算法?

[英]Algorithm to find # elements less than target in a sorted Matrix in O(n)?

Design an algorithm that outputs the number of entries in A that are smaller than or equal to x.设计一个算法,输出 A 中小于或等于 x 的条目数。 Your algorithm should run in O(n) time.您的算法应该在 O(n) 时间内运行。

For example in the array below if my target was '5' then I would return 2 b/c 1 and 3 are smaller.例如在下面的数组中,如果我的目标是“5”,那么我会返回 2 b/c 1 和 3 更小。

[1, 3,  5]
[2, 6,  9]
[3, 6, 10]

I gave it a shot with the code below which is close to working and I think it's O(n) ... the problem I see is if I don't have the # in my array I am not sure if I am returning the right value?我用下面的代码试了一下,它接近工作,我认为它是 O(n) ...我看到的问题是,如果我的数组中没有 # 我不确定我是否要返回正确的价值?

def findLessX(m,n,x):
    i = 0
    j = n-1

    while (i < n and j >= 0):
        if i == n or j == n:
            print("n not found")
            return (i+1)*(j+1)-1


        if (m[i][j] == x):
            print(" n Found at ", i , " ", j)
            return (i+1)*(j+1)-1
        elif (m[i][j] > x):
            print(" Moving left one column")
            j = j - 1
        elif (m[i][j] < x):
            print(" Moving down one row")
            i = i + 1

    print(" n Element not found so return max")
    return (i)*(j+1)

# Driver code
x = 5
n = 3
m = [ [1, 3, 5],
      [2, 6, 9],
      [3, 6, 9]]
print("Count=", findLessX(m, n, x))

Inspect the Count and simple matrix above to see if soln works ~检查上面的 Count 和简单矩阵,看看 soln 是否有效~

If both columns and rows are sorted ascending, then for any given border value some stairs line does exist.如果列和行都按升序排序,那么对于任何给定的边界值,确实存在某些阶梯线。 It divides matrix into two parts - higher (and equal) and lower than border value.它将矩阵分为两部分 - 高于(等于)和低于边界值。 That line always goes left and down (if traversal starts from top right corner).那条线总是向左和向下(如果遍历从右上角开始)。

[1, 3,  |5]
    ____|
[2,| 6,  9]
[3,| 6, 10]

So scan from top right corner, find starting cell for that line on the right or top edge, then follow the line, counting elements being left to it.因此,从右上角开始扫描,在右侧或顶部边缘找到该行的起始单元格,然后跟随该行,计算左侧的元素。

Complexity is linear, because line never turns back.复杂性是线性的,因为线永远不会回头。

PPS I hoped that you could write code with given clues PPS 我希望你能用给定的线索写代码

def countLessX(m,n,x):
    col = n-1
    count  = 0

    for row in range(n):
        while (col >= 0) and (m[row] [col] >= x):
            col = col - 1
        count = count + col + 1
    if col < 0:   #early stop for loop
        break
    return count

# Driver code
n = 3
m = [ [1, 3, 5],
      [2, 6, 9],
      [3, 6, 9]]
for x in range(11):
   print("x=", x, "Count=", countLessX(m, n, x))

x= 0 Count= 0
x= 1 Count= 0
x= 2 Count= 1
x= 3 Count= 2
x= 4 Count= 4
x= 5 Count= 4
x= 6 Count= 5
x= 7 Count= 7
x= 8 Count= 7
x= 9 Count= 7
x= 10 Count= 9

As mentioned in my comment your problem is not solveable in O(n) for most matrices.正如我在评论中提到的,对于大多数矩阵,您的问题在 O(n) 中无法解决。 Some other thoughts:其他一些想法:

  • Why count j downwards?为什么向下数 j?
  • i and j can never become n ij永远不会变成n

Here is a solution in O(n) that perhaps fullfills your needs.这是 O(n) 中的解决方案,可能满足您的需求。

Here is the adapted code:这是改编后的代码:

def findLessX(m,n,x):
  i = 0
  j = 0

  while True:
    if i+1<n and m[i+1][j]<x:
      i=i+1
    elif j+1<n and m[i][j+1]<x:
      j=j+1
    else:
      print("n found at ", i+1 , " ", j+1, "or element not found so return max")
      return (i+1)*(j+1)

Both answers suggested above will result in O(n^2).上面建议的两个答案都将导致 O(n^2)。 In worst case, the algorithms will inspect all n^2 elements in the matrix.在最坏的情况下,算法将检查矩阵中的所有 n^2 元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM