35. 搜索插入位置
python
class Solution(object):
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left,right = 0, len(nums)-1
while left<=right:
mid = (left+right)//2
if nums[mid] == target:
return mid
elif nums[mid]<target:
left = mid+1
else:
right = mid-1
return left
时间复杂度:O(logn)
空间复杂度:O(1)
74. 搜索二维矩阵
python
class Solution(object):
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
# 一种思路是分别在行和列上进行二分查找【需要查找两次】
# 更简单的思路是,把每一行拼接在一起,就是一个升序数组
# 我们仅仅确定这个升序数组的下标和矩阵的下标对应关系即可
m,n = len(matrix),len(matrix[0])
left,right = 0,m*n-1
while left<=right:
mid = (left+right)//2
x = matrix[mid//n][mid%n]
if x == target:
return True
elif x<target:
left = mid+1
else:
right = mid-1
return False
时间复杂度:O(logmn)
空间复杂度:O(1)
34. 查找第一个和最后一个位置
34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
python
class Solution(object):
def searchBinary(self, nums, target, lower):
left,right = 0,len(nums)-1
res = len(nums)
while left<=right:
mid = (left+right)//2
# 很巧妙的写法,可以只使用一个函数
if nums[mid] > target or (lower and nums[mid]>=target):
right = mid -1
res = mid
else:
left = mid + 1
return res
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
# 我们只要想办法找到第一个等于target的下标1
# 然后找到最后一个等于target的下标2
# 所以其实是我们找到第一个大于等于的下标就是1
# 我们找到的第一个大于的下标就是2
left = self.searchBinary(nums,target,True)
right = self.searchBinary(nums,target,False)-1
if left<=right and right<len(nums) and nums[left] == target:
return [left,right]
return [-1,-1]
时间复杂度:O(logn)
空间复杂度:O(1)
33. 搜索旋转排序数组

python
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if not nums:
return -1
left,right = 0,len(nums)-1
while left<=right:
mid = (left+right)//2
if nums[mid]==target:
return mid
# 锁定查找子区间
if nums[0]<=nums[mid]:
# 此时0-mid一定有序
if nums[0]<=target<nums[mid]:
right = mid-1
else:
left = mid+1
else:
# 此时mid-(n-1)一定有序
if nums[mid]<target<=nums[-1]:
left = mid+1
else:
right = mid-1
return -1
时间复杂度:O(logn)
空间复杂度:O(1)
注意:nums[0]<=nums[mid]
如果使用严格小于号nums[0]<nums[mid]。当mid=0时,nums[0]==nums[mid],会进入else分支,错误地认为右半部分有序。但此时左半部分(只有一个元素)实际上是有序的,而右半部分可能无序。例如,在nums=[3,1]中查找target=1:
- 第一次循环:
left=0, right=1, mid=0,nums[mid]=3≠1,由于nums[0]<nums[mid]为假,进入else。 - 判断
nums[mid]< target<= nums[-1]即3 < 1 <= 1为假,于是执行right = mid-1 = -1。 - 循环结束,返回
-1,但实际目标值存在(索引1)。