LeetCode 704. 二分查詢
核心:明白[left, right] 和 [left, right)兩種迴圈不變數
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1 # [left, right]
while left <= right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
else:
return mid
return -1
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) # [left, right)
while left < right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid
else:
return mid
return -1
有關二分法其他經典題目:
LeetCode 35. 搜尋插入位置
這道題實際上就是查詢target的最左側位置,如果沒有就是第一個大於target的位置
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)
while left < right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid
return left
LeetCode 34. 在排序陣列中查詢元素的第一個和最後一個位置
這一題就是“二分查詢”集大成者
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def _left():
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
if left == len(nums):
return -1
if nums[left] != target:
return -1
return left
def _right():
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] > target:
right = mid - 1
else:
left = mid + 1
if right == -1:
return -1
if nums[right] != target:
return -1
return right
return [_left(), _right()]
LeetCode 33. 搜尋旋轉排序陣列
有關“二分查詢”的主要變式
要注意if nums[mid] >= nums[left]中的“=”需要算在左崖上
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
if nums[mid] >= nums[left]:
if nums[mid] > target and target >= nums[left]:
right = mid -1
else:
left = mid + 1
else:
if nums[mid] < target and target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
LeetCode 74. 搜尋二維矩陣
LeetCode 153. 尋找旋轉排序陣列中的最小值
LeetCode 4. 尋找兩個正序陣列的中位數
LeetCode 27. 移除元素
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow, fast = 0, 0
while fast < len(nums):
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
977. 有序陣列的平方
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
left, right = 0, len(nums) - 1
res = [None] * len(nums)
p = len(nums) - 1
while left <= right:
if abs(nums[left]) < abs(nums[right]):
res[p] = nums[right] ** 2
right -= 1
else:
res[p] = nums[left] ** 2
left += 1
p -= 1
return res