代码改变世界

[LeetCode] 74. Search a 2D Matrix_Medium tag: Binary Search

2018-08-30 11:08  Johnson_强生仔仔  阅读(232)  评论(0编辑  收藏  举报

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

Example 1:

Input:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 3
Output: true

Example 2:

Input:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 13
Output: false

1) 第一种思路为 因为每行是sorted, 并且后面的row要比前面的要大, 所以我们可以将它看做是一维的sorted array 去处理, 然后去Binary Search, 只是需要注意的是num = matrix[mid//lrc[1]:列数][mid%lrc[0]:行数].

2) 第二种思路为, 找到可能在某一行(last index <= target),然后在该行中做常规的binary search
Code

1)
class Solution:
    def searchMatrix(self, matrix, target):
        if not matrix or len(matrix[0]) == 0: return False
        lrc = [len(matrix), len(matrix[0])]
        l, r = 0, lrc[0]*lrc[1] -1
        while l + 1 < r:
            mid = l + (r - l)//2
            num = matrix[mid//lrc[1]][mid%lrc[1]]
            if num > target:
                r = mid
            elif num < target:
                l = mid
            else:
                return True
        if target in [matrix[l//lrc[1]][l%lrc[1]], matrix[r//lrc[1]][r%lrc[1]]]:
            return True
        return False

 

2) 

class Solution:
    def searchMatrix(self, matrix, target):
        if not matrix or len(matrix[0]) == 0 or matrix[0][0] > target or matrix[-1][-1] < target:
            return False
        colNums = list(zip(*matrix))[0] # first column
        # find the last index <= target
        l, r = 0, len(colNums) -1
        while l + 1 < r:
            mid = l + (r - l)//2
            if colNums[mid] > target:
                r = mid
            elif colNums[mid] < target:
                l = mid
            else:
                return True
        rowNums = matrix[r] if colNums[r] <= target else matrix[l]
        l, r = 0, len(rowNums) - 1
        while l + 1 < r:
            mid = l + (r -l)//2
            if rowNums[mid] > target:
                r = mid
            elif rowNums[mid] < target:
                l = mid
            else:
                return True
        if target in [rowNums[l], rowNums[r]]: return True
        return False