1.概述
实现二分法的查准分三种情况,第一种是一种是nums = [];即l列表为空,一种是nums列表只有一个元素,nums元素个数大于1为最后一种。没找到输入[-1,-1],找到输出对应下标。nums(数组) 和target(要搜索的元素)
2.nums为空-数组为空
not nums 如果nums 为返回值为False,not使其反转为True
if not nums:
print([-1, -1])
3.len(nums)等于1
len(nums) = 1,即数组只有一个元素,若等于即第一个和最后一个都是它。没有则输出[-1,-1]。
也可以用 target in nums 判断(不推荐,毕竟学算法,尽量不用内置函数和python独有的判断符)
if nums[0] == target:
print([0, 0])
else:
print([-1, -1])
4.len(nums) 大于 1的情况
求中间值为什么不要 m1 = (l1 + r1)//2,而是下面的式子
m1 = l1 + (r1 - l1) // 2
因为r1,l1无限接近于规定的最大数,一旦相加就超过了规定的范围限制。取l1和r1的一半不会超出范围。
分别求出要找的第一个元素和最后一个元素的下标。
因为要求第一个元素,当发现nums[m1] == target时,要看它左边还有没有和它一样的数,所以m1要变小, 即右边的区间取m1,如果目标值大于取到的数组值,说明m1小了,要取右边的,l1 = m1 + 1,取l1 = m1,注意 // 2 不加一,3//2=0, 2//2=0肯会还是等于上一个m1值,会陷入死循环。而目标值小于取到的数组值不用担心,因为r1 变化大。再者出现就直接得结果了(可以自己用笔算一下)
l1 = 0
r1 = len(nums) - 1
while l1 < r1:
m1 = l1 + (r1 - l1) // 2
if nums[m1] == target:
r1 = m1
elif nums[m1] > target:
r1 = m1
elif nums[m1] < target:
l1 = m1 + 1
if nums[l1] == target:
R1 = l1
求最后一个元素,比求第一个元素要注意的是如果nums[m2] == target,你要注意取右边的数,所有m2值变大,l2 = m2 + 1 ,这里也要注意 // 2 不加一的话,3//2=0, 2//2=0,会陷入死循环。我写的代码,发现后面没有相等的值了,就直接停止循环,输出 r2 = m2.
l2 = 0
r2 = len(nums) - 1
while l2 < r2:
m2 = l2 + (r2 - l2) // 2
if nums[m2] == target:
if nums[m2 + 1] == target:
l2 = m2 + 1
else:
r2 = m2
break
elif nums[m2] < target:
l2 = m2 + 1
elif nums[m2] > target:
r2 = m2
R2 = r2
最终实现代码
nums = list(map(int,input().split(' '))) //加的输入,可不用。
target = int(input())
R1 = -1
R2 = -1
if not nums:
print([-1, -1])
elif len(nums) == 1:
if nums[0] == target:
print([0, 0])
else:
print([-1, -1])
else:
l1 = 0
r1 = len(nums) - 1
while l1 < r1:
m1 = l1 + (r1 - l1) // 2
if nums[m1] == target:
r1 = m1
elif nums[m1] > target:
r1 = m1
elif nums[m1] < target:
l1 = m1 + 1
if nums[l1] == target:
R1 = l1
l2 = 0
r2 = len(nums) - 1
while l2 < r2:
m2 = l2 + (r2 - l2) // 2
if nums[m2] == target:
if nums[m2 + 1] == target:
l2 = m2 + 1
else:
r2 = m2
break
elif nums[m2] < target:
l2 = m2 + 1
elif nums[m2] > target:
r2 = m2
R2 = r2
if R1 == -1:
print([-1, -1])
else:
print([R1, R2])