剑指offer系列-面试题-4 - 二维数组中的查找(python)

1. 题目

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

例如,下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回True;如果查找数字5,由于数组总不含有该数字,则返回False。

1289
24912
471013
681115

2. 解题思路

当我们需要解决一个复杂的问题时,一个很有效的办法就是从一个具体的问题入手。通过分析简单具体的例子,找出普遍的规律。

2.1 思路1

最笨的方法,使用两层遍历来遍历二维数组中的每一个元素,看是否含有该数字。很明显,这种思路并没有用上条件每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序
若该数组为n行m列,则时间复杂度O(n*m),空间复杂度S(1)。

2.2 思路2

在思路1的基础上,对每一行元素利用二分查找算法来判断目标数字是否在本行之内。

若该数组为n行m列,则时间复杂度O(nlogm),空间复杂度S(1)。

2.3 思路3

充分利用条件每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序,在每次判断的时候,用每一行的最小值去比较,那么如果比最大还大或者比最小还小,就直接能排除掉这一行。或者是,用每一列的最大/最小值去比较,那么如果比最大还大或者比最小还小,就直接能排除掉这一列。

只能从二维数组的左下或右上角元素开始比较,如果从左上或右下角比较的话,比左上角大的时候既不能排除一行也不能排除一列,比右下角小的情况也是类似。

若该数组为n行m列,则时间复杂度O(n+m),空间复杂度S(1)。

3. 代码实现

3.1 解法一

思路1的代码实现:

class Solution:
	def __init__(self):
		pass

	def find_in_matrix(self, matrix, target):
		"""在二维数组中查找是否含有某元素
		:param matrix: 二维数组
		:param target: 目标元素
		"""
		for row in matrix:
			for element in row:
				if element == target:
					return True

		return False
		

3.2 解法二

在思路1中每次判断只能排除掉1个值,思路2中的每次判断能排除更多的值,效率也更高。当然这种思路也可以通过递归来实现。

思路2的代码实现:

class Solution:
	def __init__(self):
		pass
		
	def find_in_matrix(self, matrix, target):
		"""在二维数组中查找是否含有某元素
		每次判断排除掉一行或是一列元素
		:param matrix: 二维数组
		:param target: 目标元素
		"""
		if matrix and len(matrix) > 0 and len(matrix[0]) > 0:
			for row in matrix:
				left = 0
				right = len(row) - 1

				while left <= right:
					mid = (left + right) // 2
					if row[mid] == target:
						return True
					elif row[mid] > target:
						right = mid - 1
					else:
						left = mid + 1

		return False

3.3 解法三

在思路1中每次判断只能排除掉1个值,思路3中的每次判断能排除一行或是一列的值,当然效率更高。

思路3的代码实现:

class Solution:
	def __init__(self):
		pass

	def find_in_matrix(self, matrix, target):
		"""在二维数组中查找是否含有某元素
		每次判断排除掉一行或是一列元素
		:param matrix: 二维数组
		:param target: 目标元素
		"""
		found = False
	
		if matrix and len(matrix) > 0 and len(matrix[0]) > 0:
			rows = len(matrix)
			columns = len(matrix[0])

			row = 0
			column = columns - 1
			while row < rows and column >=0:
				if matrix[row][column] == target:
					found = True
					break
				elif matrix[row][column] > target:
					column -= 1
				else:
					row += 1
			return found
		

4. 总结

结合之间学习的二分查找算法(每次排除当前剩余的一般的元素)和这次的二维数组查找,我发现查找类的算法,都有一个特点:

  1. 一定会与全部或某些元素进行比较;
  2. 通过比较排除1个或多个元素;
  3. 通过每次比较能够排除掉的元素越多,那么这种算法的效率也就越高;

5. 参考文献

[1] 剑指offer丛书
[2] 剑指Offer——名企面试官精讲典型编程题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值