劍指offer---二位數組中的查找

劍指offer—二位數組中的查找

問題分析

這一類題目的要求在給定的二維數組中判斷給定的數是否存在,不存在就返回False。這些二維數組有一定的規律性,比如每一行和每一列都是遞增的等等,所以在遇到二維數組或多維數組時,先看看數組是否具有一定的規律性。
下面,介紹幾種比較常用的方法。
首先,最直接的方法,就是暴力求解,用這種方法最後的時間複雜度爲O(MN)(M爲行數,N爲列數),效率是最慢的,所以這裏不推薦。

其次,還有一種使用二分法來解題的,比如像下面的二維數組:在這裏插入圖片描述
它要求每一行從左向右遞增,而且每行的第一個元素大於上一行最後一個元素。這樣的二維數組可以直接“展開”一維數組,如下:
在這裏插入圖片描述
這樣的話,就相當於在一個一維數組中判斷元素是否存在了,這裏用二分法求解,只不過每次得將一維的座標轉換成二維的座標。該方法的時間複雜度爲O(log(MN))。

最後,介紹一種線性時間的方法(這種方法的適用範圍要比第二種方法廣),也是書上提供的方法,就是根據要找的數與給定位置數的相對大小,來進一步縮小數組的範圍。
在這裏插入圖片描述
用上面的數組作爲例子,該數組的每一行從左向右遞增,每一列從上到下也是遞增的,和第一個例子有些不同。
假設需要尋找的數是7,而我們最先從右上角的9開始尋找。如果給定的數小於7,那麼根據數組的特點,比9小的數只會出現在當前列前面的列中;同樣,如果要找的數大於9,那麼只會出現在當前行的下面的行中。這樣一來,就縮小了數組的尺寸,在新的數組中還是從最右上角的位置開始找起。在這裏插入圖片描述
這一題,由於7<9,所以,下一步需要的找的點爲9(第二行,第三列),由於7<9,所以仍是在左邊查找,下一個位置爲4:
在這裏插入圖片描述
而7>4,所以接下來從下面開始找:
在這裏插入圖片描述
這時候,正好找到的數與目標數匹配,所以返回True。如果一直沒有找到,那麼數組就會一直找到第0列或第M行,這是不允許的,直接返回False。
這種方法時間複雜度爲O(M+N)。但是要注意,開始的點不能隨便亂選,在這裏我選的是最右上角,也可以選擇左下角。選擇右上角是因爲,小於該位置的數全部在其左邊,而大於此數的數全部在其下面,這個特別的地方,決定了它可以作爲開始的位置,同樣,左下角也可以。
但如果左上角,那麼它的右邊和下面的數全部大於它,所以就沒有區分度,不便於縮小查找的範圍,右下角也是如此。

本題的思想就是減小查找的範圍,所以無論是多麼複雜的結構,只要能夠找到某種手段,能夠將問題的範圍減小,那麼做起來就方便很多。

源碼

class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
    # 二分法
    #     if matrix:
    #         m = len(matrix)
    #         n = len(matrix[0])
    #         print(m, n)
    #         left = 0
    #         right = m * n - 1
    #         while left <= right:
    #             print(left, right)
    #             mid = (left + right) // 2
    #             print(mid // n)
    #             if matrix[mid // n][mid % n] < target:
    #                 left = mid + 1
    #             elif matrix[mid//n][mid%n] > target:
    #                 right = mid - 1
    #             else:
    #                 return True
    #     return False

    # 根據數組的特點
        if matrix:
            m = len(matrix)
            n = len(matrix[0])
            col = 0
            row = n-1
            while col < m and row >= 0:
                if matrix[col][row] == target:
                    return True
                elif matrix[col][row] > target:
                    row -= 1
                else:
                    col += 1
        return False

由於劍指offer上面的很多題目都能在leetcode上找到原型,所以這裏代碼用的例子也是leetcode裏的,下面是原題,大家可以使用這裏的題目來練習。

leetcode第74題. 搜索二維矩陣

第240題.搜索二維矩陣 II

謝謝

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章