704:二分查找
首先来做下这道比较简单但是容易出错的二分查找。本题比较关键的点在于区间的选择,只要在写的过程中保持区间一致就没有问题,我在这里选择的是左闭右闭:
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right: #因为是左闭右闭,left 可以等于 right
mid = (left + right) // 2 #整除2作为mid
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
else:
return mid
else:
return -1
27:移除元素
因为这道题要求的是原地移除,一个方法就是采用快指针和慢指针,快指针逐个遍历所有元素,慢指针记录符合要求的元素个数。
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow = 0
for fast in range(len(nums)):
if nums[fast] != val:
nums[slow] = nums[fast] #符合要求的fast的数被记录到slow数组的slow位置后
slow += 1
return slow
35:搜索插入位置
题目要找的元素是:第一个大于等于 target
的元素的下标。
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
else:
return mid
return right + 1 #在这道题里把right+1当作插入的位置,但是考虑插入最前面的情况了嘛
34:查找元素位置
输出元素的第一个和最后一个位置
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def lower_bound(nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1 #[mid+1, right]
else:
right = mid - 1 #[left, mid-1]
return left
#输出的这个left是数组里面target的第一个的下标
start = lower_bound(nums,target)
if start == len(nums) or nums[start] != target:#不等于或者等于nums长度说明没找到
return [-1,-1]
end = lower_bound(nums,target+1) - 1
return [start,end]
后两道题的关键在于,通过二分法,灵活的输出 left/right+1 作为结果,后续还需要多多练习!!!