题目描述

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

解题思路:

通过循环遍历二维数组中所有元素值与target值进行比较(暴力破解,非常好理解,不过复杂度相对高一点,但是也能编译通过)

时间复杂度为O(n^2)

附python代码:

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        col = len(array[0]) #列
        row = len(array) #行
        for i in range(0,col):
            for j in range(0,row):
                if target == array[i][j]:
                   return True
        return False

其他解题思路:

题意中指出 :每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。然而上面那种解题思路没有用到这个,即便不是有序的数组,一样可以查找到目标值target。但是题目给了有序的先决条件,这足以说明这道题一定有巧妙地解法。

每一行都按照从左到右递增的顺序排序,这样的数组

【 [ 1  2  3  4 ]

     [ 5  6  7  8 ]】

如果我们要找 target=5,通过比较第一行最后一个元素值 我们就能知道target=5 > 4 所以根据题意每一行都按照从左到右递增的顺序排序,我们要找的target值肯定不在第一行,减少了遍历第一行的次数,我们再去将target值与第二行最后一个元素比较,target=5 < 8 所以这个target值如果存在于这个数组中(数组中可能不存在目标值,返回False)则它肯定在这行中,我们在从这行最后一个元素向前遍历,就能找到目标值target了 。如果我们要找目标值target = 3  它小于 4 我们就知道它如果存在 就只能在第一行中。

时间复杂度为O(n)

附代码:

class Solution:
    def Find_test(self, target, array):
        # write code here
        col = len(array[0]) #列
        row = len(array) #行
        i=0
        j=col-1
        while(i < row and j >=0):
            if target > array[i][j]:
                i+=1
            elif target < array[i][j]:
                j-=1
            else:
                return True
        return False 
if __name__ == '__main__':
    s=Solution()
    print(s.Find_test(9,[[1,3,4,7],[2,5,6,8]]))

二分查找的解题思路:

复杂度相对高一点的   分别对每一行进行二分查找,还有一种是对整个数组进行拆分。

对于传统二分查找算法:

  1. 定义: 二分查找又称折半查找,它是一种效率较高的查找方法。二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。不妨设有序表是递增有序的。
  2. 算法思想:  设R[low..high]是当前的查找区间
    (1)首先确定该区间的中点位置:mid = (low + high) /2
    (2)然后将待查的K值与R[mid].key比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:
           ①  若R[mid].key>K,则由表的有序性可知R[mid..n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1..mid-1]中,故新的查找区间是左子表R[1..mid-1]。
           ②  若R[mid].key<K,则要查找的K必在mid的右子表R[mid+1..n]中,即新的查找区间是右子表R[mid+1..n]。下一次查找是针对新的查找区间进行的。
    因此,从初始的查找区间R[1..n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。
  3. 代码(python):
'''
二分查找
'''

class Solution:
    def BinarySearch(self , key , A):
        low = 0
        high = len(A)
        mid = int((low+high)/2)
        if key == A[mid]:
            return True
        elif key > A[mid]:
            low = mid + 1
            mid = int((low+high)/2)
        else:
            high = mid - 1
            mid = int((low+high)/2)
        return False
        
if __name__=="__main__":
    s=Solution()
    print(s.BinarySearch(5,[1,2,3,4,6,9,12,16]))

待更新。。。。

 

 

总结:
关于查找类型的题,要先看给定的数据是否有序;对于有序的数据要利用它有序的特点,应用特殊的解法。如:二分查找,找特殊起始点等.