二分法之查找最接近目标数的数
def erfen(nums, target):
left = 0
right = len(nums) - 1
while left < right:
mid = (left+right)//2
if nums[mid] > target:
right = mid - 1
elif nums[mid] <= target:
left = mid + 1
return nums[:left] + [target] + nums[left:]
二分法要注意的点是 分的是下标,然后注意+1更新,因为判断之后,如果不等于mid,则下一个范围不用包含上一个mid。
注意一上来先排除特殊情况,最大小值。
def erfen1(nums,a):
min = 0
max = len(nums) - 1
if a > nums[max] or a < nums[min]:
return []
while max >= min:
mid = int((max+min)/2)
if a == nums[mid]:
return mid
elif a > nums[mid]:
min = mid+1
else:
max = mid-1
return []
print(erfen1([3,4,5,6,7,8,9],9))
def binarysearch(s, target):
min = 0
max = len(s)
if s[min] > target or s[max] < target:
return
while min < max:
mid = (min + max)//2
if s[mid] < target:
min = mid + 1
elif s[mid] > target:
max = mid - 1
else:
return mid
return
时间复杂度是O(logn)
如何看呢,原来的长度是n,每一次划分都是除以2,最后的长度是1,所以等式
x代表的是二分的次数。x = log(n) 。2在这里可以不写,与5n的系数不写的道理一样。
边界问题是模糊的点!注意!
class Solution(object):
def minArray(self, numbers):
"""
:type numbers: List[int]
:rtype: int 使用min 和 mid比较不太好,因为这个变化规律可能出现在后半部分递增的数组里
"""
if not numbers:
return
min = 0
max = len(numbers)-1
# mid = (min + max)//2
while min <= max:
mid = min + (max-min)//2
if numbers[max] < numbers[mid]:
min = mid + 1
elif numbers[max] > numbers[mid]:
max = mid
else:
max -= 1 # [2,2,2,2,2,1,2,2,2,2]
#当遇到相等的时候,可以往左移动一位,活起来;
#或者当min==max的时候,跳出循环。
return numbers[min]
缺失数字
class Solution:
def solve(self , a ):
# write code here
# partition 如果该位置的数大于序号,说明前面缺失,如果等于序号,说明不缺失
left = 0
right = len(a) - 1
while left <= right:
mid = (left + right) // 2
if a[mid] > mid:
right = mid - 1
else:
left = mid + 1
return left # right + 1最后必须right+1,因为最后一个判断还减去1