题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路:
通过循环遍历二维数组中所有元素值与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]]))
二分查找的解题思路:
复杂度相对高一点的 分别对每一行进行二分查找,还有一种是对整个数组进行拆分。
对于传统二分查找算法:
- 定义:
二分查找又称折半查找,它是一种效率较高的查找方法。二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。不妨设有序表是递增有序的。
- 算法思想:
设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的结点,或者直至当前的查找区间为空(即查找失败)时为止。
- 代码(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]))
待更新。。。。
总结:
关于查找类型的题,要先看给定的数据是否有序;对于有序的数据要利用它有序的特点,应用特殊的解法。如:二分查找,找特殊起始点等.