33. 搜索旋转排序数组
image-20201202152424398
思路
- 二分法
先对着代码进行讲解。
class Solution: def search(self, nums: List[int], target: int) -> int: # low和high分别指向数组2端 low, high = 0, len(nums)-1 while low <= high: mid = (low+high) // 2 # 如果nums[mid]与目标相等,直接return,这里没有异议 if nums[mid] == target: return mid elif nums[mid] > target: # 这里开始出现分歧,虽然中位数大于了目标,由于存在 # 旋转的可能,如果低位也大于目标且低位到中位是递增的 # 那么可以肯定左半段没有等于target的数了,所以往右侧找 if nums[low] > target and nums[low] <= nums[mid]: low = mid+1 # 否则与正常二分保持一致 else: high = mid-1 else: # 同上 if nums[high] < target and nums[high] >= nums[mid]: high = mid - 1 else: low = mid + 1 return -1
虽然这个数组是被旋转了,但是也满足二分搜索条件,只不过需要做一定的转换。 我们来看下面这个例子: [5, 1, 3] 当目标元素是5的时候,首先二分会找到1,按照以往的数组,这时候low应该等于mid+1,但在这里不一样,因为数组有可能已经被旋转了。 所以需要往左侧走,high = mid-1,当然这个也是有条件的,那就是此时nums[high]也比target小,并且nums[high]要保证大于nums[mid],也就是说后半段要是递增的,那就肯定没有数字比target大了,这时候才会去左边查找。 同理当target比nums[mid]小的时候也是一样。
image-20201202153406536
里面还是有许多坑的,比如递增的条件一定要≥,否则有部分用例会发现你的bug。 大家写完之后可以多写点特殊场景的用例自测一下再提交,通过的概率会大很多!