美团二面面到了~
归根结底还是范围的缩小!
旋转数组最小数字
1、旋转数组的难点是在是否有重复的数字,下面这题是有的,所以直接与最后的一位/第一位比较来判断是否属于左边的数组还是右边的数组是不可行的。但是因为只是找最小的,所以还可~注意缩小范围的方法: 如果mid值大于right,必然在左边的数组,故left=mid+加一个判断条件,如果left=mid,直接跳出; 如果mid小于right,其实错: 可能是左边也可能是右边的数组,只可能是右边的数组,所以 right = mid ; 如果mid等于right, right-=1 — 因为可能有重复,所以不可以直接返回。
为什么这里的right不会是左数组的,因为如果大于right, 从一开始他就不会收缩~所以肯定是硬耗到到达右数组
跟找target的区别就是最小的数肯定是在右数组,但是tar不一定啊
class Solution:
def minNumberInRotateArray(self, rotateArray):
if not rotateArray:
return 0
left = 0
right = len(rotateArray) - 1
while left < right:
mid = (left + right)//2
if rotateArray[mid] > rotateArray[right]:
if left == mid:
## 这个判断是关键的~否则 比如3 2,范围就不会缩小
return rotateArray[right]
left = mid
elif rotateArray[mid] < rotateArray[right]:
right = mid
# 为什么这里的right不会是左数组的,因为如果大于right,
# 从一开始他就不会收缩~所以肯定是硬耗到到达右数组
# 跟找target的区别就是最小的数肯定是在右数组,但是tar不一定啊
else:
right -= 1
return rotateArray[right]
旋转数组寻找target
与上面的区别首先就是没有重复的。所以不能这个时候必须借助首尾进行判断是属于左数组还是右数组。其实这题就算是有重复的也可以照样求解~~
class Solution:
def search(self , nums , target ):
# write code here
if not nums:
return -1
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right)//2
if target == nums[mid]:
return mid
if nums[mid] < nums[-1]:
if target > nums[mid]:
if target > nums[-1]:
right = mid - 1
else:
left = mid + 1
else:
right = mid - 1
else:
if target > nums[mid]:
left = mid + 1
else:
if target <= nums[-1]:
left = mid + 1
else:
right = mid - 1
return -1