69. x 的平方根

https://leetcode-cn.com/problems/sqrtx/
边界条件的判断是二分查找的唯一难点
start最终会留在平分刚好比x小的那个位置往右一点,也就是说 Binary Search - 图1

  1. class Solution:
  2. def mySqrt(self, x: int) -> int:
  3. if x < 2:
  4. return x
  5. start = 0
  6. end = x
  7. while start <
  8. = end:
  9. midpoint = start + (end-start)//2
  10. if midpoint * midpoint < x:
  11. start = midpoint+1
  12. elif midpoint * midpoint > x:
  13. end = midpoint-1
  14. else:
  15. return midpoint
  16. return start-1

153. 寻找旋转排序数组中的最小值

https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/

  1. class Solution:
  2. def findMin(self, nums: List[int]) -> int:
  3. start = 0
  4. end = len(nums)-1
  5. while start<end:
  6. midpoint = start + (end-start)//2
  7. if nums[midpoint] > nums[end]:
  8. start = midpoint+1
  9. else:
  10. end = midpoint
  11. return nums[end]

33. 搜索旋转排序数组

https://leetcode-cn.com/problems/search-in-rotated-sorted-array/
其实相对简单的办法还是先找到数组旋转点,也就是最小值在哪里,然后将数组分为两段,根据target和两段的关系来查找
注意等号的选择!

  1. class Solution:
  2. def search(self, nums: List[int], target: int) -> int:
  3. left = 0
  4. right = len(nums)-1
  5. while left<=right:
  6. mid = left + (right-left)//2
  7. if nums[mid]==target:
  8. return mid
  9. if nums[mid]>=nums[left]:
  10. if target>=nums[left] and target<nums[mid]:
  11. right = mid-1
  12. else:
  13. left = mid+1
  14. else:
  15. if target>nums[mid] and target<=nums[right]:
  16. left = mid+1
  17. else:
  18. right = mid-1
  19. return -1

1095. 山脉数组中查找目标值

https://leetcode-cn.com/problems/find-in-mountain-array/
有点类似在搜索旋转数组,但是这道题target有可能存在于左右两边各一个
关键在于先找到峰值,然后从峰值一分为二,在两侧都寻找

  1. # """
  2. # This is MountainArray's API interface.
  3. # You should not implement it, or speculate about its implementation
  4. # """
  5. #class MountainArray:
  6. # def get(self, index: int) -> int:
  7. # def length(self) -> int:
  8. class Solution:
  9. def findMountainTop(self, mountain_arr: 'MountainArray') -> int:
  10. left = 0
  11. right = mountain_arr.length()-1
  12. while left < right:
  13. mid = left + (right-left)//2
  14. mid_val = mountain_arr.get(mid)
  15. if mid_val < mountain_arr.get(mid+1):
  16. left = mid+1
  17. else:
  18. right = mid
  19. return left
  20. def binarySearch(self, arr, target, left, right, ascend=True):
  21. while left <= right:
  22. mid = left + (right-left)//2
  23. if arr.get(mid) == target:
  24. return mid
  25. elif arr.get(mid) < target:
  26. if ascend:
  27. left = mid+1
  28. else:
  29. right = mid-1
  30. else:
  31. if ascend:
  32. right = mid-1
  33. else:
  34. left = mid+1
  35. return -1
  36. def findInMountainArray(self, target: int, mountain_arr: 'MountainArray') -> int:
  37. peek_idx = self.findMountainTop(mountain_arr)
  38. idx = self.binarySearch(mountain_arr, target, 0, peek_idx,True)
  39. if idx!=-1:
  40. return idx
  41. else:
  42. return self.binarySearch(mountain_arr, target, peek_idx, mountain_arr.length()-1, False)