举个例子:
思路
- 1 . 首先暴力法肯定可行,时间复杂度为O(n^2),这里不在贴代码了,没意思。
- 2 . 暴力法虽然可行,但是没有利用题目中已经给出的有序条件,所以这就告诫我们在解算法的时候,要充分利用已知条件来降低时间复杂度。
- 3 . 根据行列都有序,我们可以使用双指针法,一个指向行,一个指向列,来不断的缩小范围,那么从哪里开始操作,朝着什么方向移动就变成了核心问题!
- 4 . 在开始之前,我们可以先判断target是否小于左上角的元素和是否大于右下角的元素,如果满足任意一个条件则范围False;
然后我们先从左上角开始考虑:当target大于第一个值array[0][0]时,横指针和纵指针都可以移动,当我们选择移动横指针时,这意味着我们放弃了第一列的元素,而target可能在第一列,所以从左上角开始不太行。
我们再考虑从右上角开始,当我们的元素大于target时,说明不在当前行,行指针可以下移,当我们的元素小于target时,说明元素不在当前列,OK这个方法可行。
为了不失一般性,我们也考虑剩下两种情况。
从左下角开始时,当元素大于target时,说明target不在当前行,向上移动行指针;当元素大于target时向右移动列指针,这个方法也可行
从右下角开始时,当元素大于target时,我们之前就考虑过了,直接返回False。当元素大于target时,可以移动列指针也可以移动行指针,又回到了从左上角开始的情况,不可行。
综上,我们考虑从右上角或者左下角开始,充分利用有序性质移动行指针和列指针。
这里我们选择从右上角开始,代码如下:
# -*- coding:utf-8 -*-
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
row_nums = len(array)
# 对指针初始赋值,使其从右上方开始遍历
row_index = 0
column_index = len(array[0])-1
# 双指针唯一对应的值
while row_index < raw_nums and column_index >= 0:
value = array[row_index][column_index]
if value == target:
return True
elif value > target:
column_index -= 1
else:
row_index += 1
return False
时间复杂度分析
设二维数组的行数为m,列数为n,则时间复杂度为O(m+n)=O(m)=O(n)