原题链接:
https://leetcode.com/problems/search-in-rotated-sorted-array
https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array
https://leetcode.com/problems/search-insert-position
思路:
由于这几道题我都用了二分法,所以就合在一起说了
首先是第33题
将一个排列好的数组如果从某一位打乱,则要么其中点左侧数组必然升序,要么右侧数组必然升序。因此分这两种情况讨论。
当左侧为升序时,必有nums[l] < nums[mid]:此时,若target的值在这之间则target必在左边,故下一轮把数组范围缩小至左半边;若target的值不在这之间则它必在右边,故下一轮把数组范围缩小至右半(l从mid+1开始)
当右侧为升序时,必有nums[mid] < nums[r]:此时,若target的值在这之间则将搜索范围缩小至右半边(l从mid+1开始);否则把搜索范围缩小至左半(r指向mid)
当nums[mid]与target相等时,输出mid
如果最后r与l相等了还没有搜索到则输出-1
代码
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
subleft = 0
subright = len(nums)-1
while subleft <= subright:
submid = (subleft + subright) // 2
if nums[submid] == target:
return submid
if nums[subleft] <= nums[submid]:
if target >= nums[subleft] and target <= nums[submid]:
subright = submid
else:
subleft = submid + 1
else:
if target >= nums[submid] and target <= nums[subright]:
subleft = submid + 1
else:
subright = submid
return -1
第34题
依然利用二分法,首先搜索到与target相等的值,然后开始分别向左向右搜索,当左右分别出现第一个不等于target的值时,左右index各退回1并输出
代码
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
l = 0
r = len(nums) - 1
while l <= r:
mid = (l+r)//2
if target==nums[mid]:
return self.searchTarget(target, nums, mid)
elif target > nums[mid]:
l = mid + 1
else:
r = mid - 1
return -1,-1
def searchTarget(self, target, nums, cur):
left = cur
right = cur
while nums[left] == target:
left -= 1
if left < 0:
break
while nums[right] == target and right <= len(nums)-1:
right += 1
if right >= len(nums):
break
return left+1, right-1
第35题
代码
class Solution(object):
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
l = 0
r = len(nums) - 1
while l <= r:
mid = (l+r)//2
if l==r:
if target > nums[mid]:
return mid+1
else:
return mid
if target == nums[mid]:
return mid
elif target > nums[mid]:
l = mid + 1
else:
r = mid