二分查找实现条件混淆
Binary search implementation conditional confusion
我是用二分查找来解决问题的,当我看到有些地方有人使用while start < end
时我感到困惑,但在算法中我的理解是它应该是while start <= end
。
例如,这里是 Leetcode 问题的解决方案找到大于目标的最小字母:
def nextGreatestLetter (self, letters: List[str], target: str) -> str:
l, r = 0, len(letters)-1
# cross the border
if target >= letters[-1]:
return letters[0]
while l < r:
mid = (l+r)//2
if letters[mid] <= target:
l = mid+1
else:
r = mid
return letters[l]
为什么我们没有递减 r = mid - 1
并且为什么没有 while l <= r
?
我真的很困惑。
这些是实施细节。有多种实现一切的方法。
在这种情况下,循环条件是 l < r
(不是 l <= r
),因为当 l == r(即搜索中只有一个元素 space)时,我们不必进一步处理,预期结果(ceil)是位置 l
.
处的元素
并且更新语句是 r = mid
(不是 r = mid - 1
),因为更新发生在 target < letters[mid]
时,我们不能根据这个条件丢弃中间的元素。例如,假设 (mid - 1) 处的元素可能小于或等于目标,在这种情况下,我们的结果将是 mid[=33= 处的元素].
就像我说的,这些只是实现细节,同样的解决方案也可以这样实现:
def nextGreatestLetter (self, letters: List[str], target: str) -> str:
l, r = 0, len(letters)-1
# cross the border
if target >= letters[-1]:
return letters[0]
while l <= r:
mid = (l+r)//2
if letters[mid] <= target:
l = mid+1
else:
r = mid - 1
return letters[l]
我们在循环内处理 l == r
案例的实现也是正确的,并且通过了 Leetcode 上的所有测试用例。
PS:
我假设您最近开始了竞争性编码,所以这只是给您的建议。不要试图记住实现并专注于算法的关键,同样因为有多种实现相同算法的方法。
我是用二分查找来解决问题的,当我看到有些地方有人使用while start < end
时我感到困惑,但在算法中我的理解是它应该是while start <= end
。
例如,这里是 Leetcode 问题的解决方案找到大于目标的最小字母:
def nextGreatestLetter (self, letters: List[str], target: str) -> str:
l, r = 0, len(letters)-1
# cross the border
if target >= letters[-1]:
return letters[0]
while l < r:
mid = (l+r)//2
if letters[mid] <= target:
l = mid+1
else:
r = mid
return letters[l]
为什么我们没有递减 r = mid - 1
并且为什么没有 while l <= r
?
我真的很困惑。
这些是实施细节。有多种实现一切的方法。
在这种情况下,循环条件是 l < r
(不是 l <= r
),因为当 l == r(即搜索中只有一个元素 space)时,我们不必进一步处理,预期结果(ceil)是位置 l
.
并且更新语句是 r = mid
(不是 r = mid - 1
),因为更新发生在 target < letters[mid]
时,我们不能根据这个条件丢弃中间的元素。例如,假设 (mid - 1) 处的元素可能小于或等于目标,在这种情况下,我们的结果将是 mid[=33= 处的元素].
就像我说的,这些只是实现细节,同样的解决方案也可以这样实现:
def nextGreatestLetter (self, letters: List[str], target: str) -> str:
l, r = 0, len(letters)-1
# cross the border
if target >= letters[-1]:
return letters[0]
while l <= r:
mid = (l+r)//2
if letters[mid] <= target:
l = mid+1
else:
r = mid - 1
return letters[l]
我们在循环内处理 l == r
案例的实现也是正确的,并且通过了 Leetcode 上的所有测试用例。
PS: 我假设您最近开始了竞争性编码,所以这只是给您的建议。不要试图记住实现并专注于算法的关键,同样因为有多种实现相同算法的方法。