題目描述
解題思路
瞭解二分查找法
二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。但是,二分查找要求線性表必須採用順序存儲結構,而且表中元素按關鍵字有序排列。它的實質上、是不斷地將有序數據集進行對半分割,並檢查每個分區的中間元素。
舉例說明:在數組中查找值爲47的數。
實現過程是通過變量left和right控制一個循環來查找元素(其中left和right是正在查找的數據集的兩個邊界值)。
- 首先,將left和right分別設置爲0和len(nums)-1。
- 在迭代過程中,middle爲left和right之間區域的中間值。
如果middle比目標值小,將左索引值(left)移動到middle後的一個元素的位置上。即下一組要搜索的區域是middle的右半邊區域。
如果處於middle的元素比目標元素大,將右索引值移動到middle前一個元素的位置上。即下一組要搜索的區域是middle的左半邊區域。 - 最後,隨着搜索的進行,不斷重複上述步驟,一旦在middle處找到目標,查找將停止;如果沒有找到目標,left和right將重合。
時間複雜度:取決於查找過程中分區數可能的最大值。對於一個有n個元素的數據集來說,最多可以進行次分區。對於二分查找,)這表示最終可能在最壞的情況下執行的檢查的次數。
對於由n個元素的數據集,線性查找目標值,需要遍歷n個數,用到的時間複雜度爲;二分查找目標值,如果是10的數,找到4需要1次,找到7需要2,找到8需要3次,所以最壞的情況下需要查找的次數爲3:=8
(當n=8到15時,最壞情況下查找3次能找到目標值)
python代碼
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if not nums:
return -1
left = 0
right = len(nums) - 1
while left <= right:
mid = (right + left) // 2
if nums[mid] == target:
return mid
if nums[mid] >= nums[left]: # 左邊升序
# 如果不限定左邊的界限,就會出現0<7,從而找不到此值,而真實結果是存在的
if nums[left] <= target <= nums[mid]: # 在左邊範圍內
right = mid - 1
else: # 只能從右邊找
left = mid + 1
else: # 右邊升序
if nums[mid] <= target <= nums[right]: # 在右邊範圍內
left = mid + 1
else: # 只能從左邊找
right = mid - 1
return -1 # 沒找到
s = Solution()
res = s.search([4, 5, 6, 7, 0, 1, 2], 0)
print('.....',res) # 4