33搜索旋转排序数组
题目:假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是 O(log n) 级别。
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
法一:自己的代码
思路:先判段[left,mid]是否为单增区间,如果是,判断target是否在该区间中,进而缩小搜索范围,如果不是,判断target是否在[mid,right]中,同理缩小搜索范围,注意用这个方法时,必须用left <= right判断,因为要用nums[right]判断与target的大小,所以right=len(nums)-1,用右闭区间,所以用left <= right,另外要注意[5,9],target=9这种情况。
# 原先的程序 # from typing import List # class Solution: # def search(self, nums: List[int], target: int) -> int: # left = 0 # right = len(nums) - 1 # def recursion(left=0, right=right): # # if left == right: # # return nums[left] # if nums[left] == target: # return left # elif nums[right] == target: # return right # elif left == right: # return -1 # mid = left + (right - left) // 2 # # if target > nums[mid]: # if nums[mid] > nums[left]: # if target > nums[mid] or target < nums[right]: # return recursion(left=mid, right=right) # else: # return recursion(left=left, right=mid) # elif target > nums[left] or target < nums[mid]: # return recursion(left=left, right=mid) # else: # return recursion(left=mid, right=right) # return recursion(left, right) # from typing import List # class Solution: # def search(self, nums: List[int], target: int) -> int: # left = 0 # right = len(nums) - 1 # l = right # if right == -1: # return -1 # def judge(left, right): # # 这里是 # while left <= right: # mid = (left + right) >> 1 # if nums[mid] == target: # return mid # if nums[mid] > target: # right = mid - 1 # elif nums[mid] < target: # left = mid + 1 # if nums[left] == target: # return left # else: # return - 1 # while left <= right: # mid = (left + right) >> 1 # if nums[mid] == target: # return mid # # 如果大于,说明左边为单增区间, # if nums[mid] > nums[left]: # # 如果在该区间里面,直接搜索寻找 # if target >= nums[left] and target < nums[mid]: # return judge(left, mid-1) # # 否则说明在另一个区间里 # else: # left = mid + 1 # # 否则右边为单增区间 # # mid+1有可能超过区间,所以取其和l的最小值 # elif target >= nums[min(mid+1, l)] and target <= nums[right]: # # mid+ # return judge(mid+1, right) # else: # right = mid - 1 # return left if nums[left] == target else -1 # 改进后的程序 from typing import List class Solution: def search(self, nums: List[int], target: int) -> int: left = 0 right = len(nums) - 1 l = right if right == -1: return -1 while left <= right: mid = (left + right) >> 1 if nums[mid] == target: return mid # 如果大于,说明左边为单增区间, # 这里必须是等于等于,因为有[5,9],target=9这种情况 if nums[mid] >= nums[left]: # 如果在该区间里面,直接搜索寻找 if target >= nums[left] and target < nums[mid]: right = mid - 1 # 否则说明在另一个区间里 else: left = mid + 1 # 否则右边为单增区间 elif target > nums[mid] and target <= nums[right]: left = mid + 1 else: right = mid - 1 return left if nums[left] == target else -1 if __name__ == '__main__': solution = Solution() # result = solution.search(nums=[6,7,8,9,10,11,12,1,2,3], target=4) result = solution.search(nums=[5,3], target=3) # result = solution.search(nums = [2,3,4,5,6,7,8,9,1], target = 3) print(result)
ttt