[Leetcode]Search a 2D Matrix

来源:互联网 发布:淘宝账号申诉 编辑:程序博客网 时间:2024/05/16 10:31

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.

For example,

Consider the following matrix:

[  [1,   3,  5,  7],  [10, 11, 16, 20],  [23, 30, 34, 50]]

Given target = 3, return true.

在一个二维的矩阵里查找某个元素是否存在~矩阵每一行都是有序的,并且下一行的第一个元素值比这行的最后一个元素值大~

记得貌似在剑指offer这本书里看到过一个类似的题,那道题里矩阵的每行每列也都是是有序的,但不保证下一行的第一个元素值比这行的最后一个元素值大,思路是采取右上角的一个数字,与target比较,如果相同的话,返回True;如果右上角的值小于target,则target不可能在这一行里,可以把这一行剔除掉(维护两个index);如果值大于target,则说明target不可能在这一列,把这一列剔除掉;这样每一步都可以缩小查找的范围~算法时间复杂度应该是O(m+n)~   代码如下(写的时候对这题还有点印象,然后一次就AC了偷笑)

class Solution:    # @param matrix, a list of lists of integers    # @param target, an integer    # @return a boolean    def searchMatrix(self, matrix, target):        if matrix is None or len(matrix) == 0 or len(matrix[0]) == 0: return False        row, col = len(matrix), len(matrix[0])        i, j = 0, col - 1        while i < row and j >= 0:            if matrix[i][j] == target:                return True            elif matrix[i][j] > target:                j = j - 1            else:                i = i + 1        return False

看了一下其他解法~在时间复杂度上还可以提升~可以进行两次二分查找,把时间复杂度改进为O(logm + logn)~先按行查找,定位到某行,然后再按列查找~代码如下(写的时候要注意一下第一个二分搜索, 容易出错)

class Solution:    # @param matrix, a list of lists of integers    # @param target, an integer    # @return a boolean    def searchMatrix(self, matrix, target):        if matrix is None or len(matrix) == 0 or len(matrix[0]) == 0: return False        rowLen, colLen = len(matrix), len(matrix[0])        l, r = 0, rowLen - 1        while l <= r:            mid = l + (r - l) / 2            if matrix[mid][0] == target: return True            elif matrix[mid][0] > target: r = mid - 1            else: l = mid + 1        row = r         if row < 0: return False        l, r = 0, colLen - 1         while l <= r:            mid = l + (r - l) / 2            if matrix[row][mid] == target: return True            elif matrix[row][mid] > target: r = mid - 1            else: l = mid + 1        return False

还有另外一种解法,就是把2维矩阵当成一个1维的数组,然后在一维数组里用二分搜索查找~简化成的一维数组长度为rowLen * colLen; 中间值在二维矩阵里对应的是matrix[mid / colLen][mid % colLen]~ 时间复杂度是O(log(m*n)) = O(logm + logn),与进行两次二分搜索的复杂度一样~ 但有人认为这种解法还有一些缺陷:首先,m*n可能会溢出;其次,引进了大量的复杂运算:/ 和 % ~ (不过python 自带大数整数运算,整数不会溢出,只要内存足够)

class Solution:    # @param matrix, a list of lists of integers    # @param target, an integer    # @return a boolean    def searchMatrix(self, matrix, target):        if matrix is None or len(matrix) == 0 or len(matrix[0]) == 0: return False        rowLen, colLen = len(matrix), len(matrix[0])        l, r = 0, rowLen * colLen - 1        while l <= r:            mid = l + (r - l) / 2            midVal = matrix[mid / colLen][mid % colLen]            if midVal == target: return True            elif midVal < target:                l = mid + 1            else:                r = mid - 1        return False


0 0