我阅读了Binary search algorithm - Wikipedia,一分为二地搜索了重复项的最左侧元素
伪代码:
function binary_search_leftmost(A, n, T):
L := 0
R := n
while L < R:
m := floor((L + R) / 2)
if A[m] < T:
L := m + 1
else:
R := m
return L
在python中实现
def search_leftmost(nums: List[int], target: int) -> List[int]:
if len(nums) < 1: return [-1, -1]
lo = 0
hi = len(nums)
logging.debug(f"nums:{list(enumerate(nums))}, target: {target}")
while lo < hi:
mid = (lo+hi) // 2
logging.debug(f"lo:{lo} mid:{mid} hi:{hi}")
if target > nums[lo]:
lo = mid + 1
else:
hi = mid
logging.debug(f"lo: {lo}")
return lo
不幸的是,当使用nums = [5,7,7,8,8,8,8,10]; target = 8
$ python 0.bi_search.py
DEBUG nums:[(0, 5), (1, 7), (2, 7), (3, 8), (4, 8), (5, 8), (6, 8), (7, 10)], target: 8
DEBUG lo:0 mid:4 hi:8
DEBUG lo:5 mid:6 hi:8
DEBUG lo:5 mid:5 hi:6
DEBUG lo: 5
返回5,它既不是最左也不是最右。
我的实现有什么问题?
答案 0 :(得分:1)
问题出在执行中。
伪代码
if A[m] < T:
L := m + 1
实现为
if target > nums[lo]: # this should be if nums[mid] < target:
lo = mid + 1
我已对其进行更新,并且它按预期运行:
def search_leftmost(nums, target):
lo = 0
hi = len(nums)
while lo < hi:
mid = (lo+hi) // 2
if nums[mid] < target:
lo = mid + 1
else:
hi = mid
return lo
if __name__ == "__main__":
nums = [5,7,7,8,8,8,8,10]
target = 8
assert search_leftmost(nums, target)== 3
nums = [5,7,7,8,8,8,8,10]
target = 7
assert search_leftmost(nums, target) == 1
nums = [5,7,7,8,8,8,8,10]
target = 10
assert search_leftmost(nums, target) == 7
print("Done")
根据Wiki:
即使T不在数组中,L 是T在数组中的排名,还是 数组中小于T的元素。