题目描述
解题思路
了解二分查找法
二分查找也称折半查找(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