舉個例子:
思路
- 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)