1.题目描述
2.思路
方法1(自己想的):首先用分治法找到数组前半段和后半段的衔接处separate,若target刚好在nums[: separate]或nums[separate + 1 :]里则在对应区间里二分查找target,否则直接返回-1。
方法2(受灵茶山艾府佬题解的启发):不停二分,判断nums[mid]与nums末尾元素的大小关系,如果nums[mid] < nums[-1],那么分割点separate一定在[left, mid - 1]上,否则分割点separate就在[mid + 1, right]上,找到separate之后就和方法1一样,若target刚好在nums[: separate]或nums[separate + 1 :]里则在对应区间里二分查找target,否则直接返回-1。
3.代码(Python3)
方法1:
class Solution:
def search(self, nums: List[int], target: int) -> int:
def search_separate(left, right):
if left > right: return -1
elif left == right and nums[left] == target: return left
mid = (left + right) // 2
if mid + 1 == len(nums): return -1
if nums[mid] > nums[mid + 1]: return mid
separate = search_separate(left, mid - 1)
if separate == -1: separate = search_separate(mid + 1, right)
return separate
separate = search_separate(0, len(nums) - 1)
if separate == -1: separate = len(nums) - 1 # nums没有旋转的情况
elif nums[separate] == target: return separate
elif target < nums[separate + 1] or target > nums[separate]: return -1
left, right = 0, separate
if separate != len(nums) - 1 and target <= nums[-1]: left, right = separate + 1, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target: return mid
elif nums[mid] > target: right = mid - 1
else: left = mid + 1
return -1
方法2:
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < nums[-1]: right = mid - 1
elif nums[mid] > nums[-1]: left = left + 1
else: break
separate = left - 1
if left == 0: separate = len(nums) - 1 # nums没有旋转的情况
elif target < nums[separate + 1] or target > nums[separate]: return -1
left, right = 0, separate
if separate != len(nums) - 1 and target <= nums[-1]: left, right = separate + 1, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target: return mid
elif nums[mid] > target: right = mid - 1
else: left = mid + 1
return -1
4.执行情况
方法1:
方法2:
5.感想
我写的方法虽然执行效果还可以,但代码可读性极差,是在一次一次通不过测试用例的过程中不断修补的,所以看起来非常东拼西凑,差评!灵茶山艾府佬的题解思想非常妙,但是应用在我的代码里效率反而没那么高,不知道为什么。