33. 搜索旋转排序数组

image.png

nums[left] <= nums[mid]
此时前半部分是升序序列
(1) 若nums[left] <= target <= nums[mid],则表示target在前半部分有序的范围内存在
right = mid - 1
(2) 若target < nums[left] <= nums[mid], 则表示target小于前半部分升序序列中最小值,不能再前半部分序列中查找,需要在后半部分序列中查找
left = mid + 1
(3) 若nums[left] <= nums[mid] < target, 则表示target大于前半部分升序序列中最大值,也不能再前半部分序列中查找,需要在后半部分序列中查找
left = mid + 1

nums[left] > nums[mid] 即:nums[mid] <= nums[right]
此时后半部分序列有序
(1) 若nums[mid] <= target <= nums[right],则表示target在后半部分有序列的范围内存在
left = mid + 1
(2) 若target < nums[mid] <= nums[right],则表示target小于后半部分升序序列中最小值,不能再后半部分序列中查找,需要在前半部分序列中查找
right = mid - 1
(3) 若nums[mid] <= nums[right] < target, 则表示target大于后半部分升序序列中最大值,也不能再后半部分序列中查找,需要在前半部分序列中查找
right = mid - 1

二分查找

  1. package main
  2. import "fmt"
  3. func search(nums []int, target int) int {
  4. left :=0
  5. right :=len(nums)-1
  6. for left<=right{
  7. mid :=left+(right-left)>>1
  8. if nums[mid]==target{
  9. return mid
  10. }else if nums[left]<=nums[mid]{//中间值递增序列
  11. if nums[left]<=target&&target<nums[mid]{
  12. right=mid-1
  13. }else {
  14. left= mid+1
  15. }
  16. }else {// 中间值右边递增序列
  17. if nums[mid]<target&&target<=nums[right] {
  18. left = mid+1
  19. }else {
  20. right = mid-1
  21. }
  22. }
  23. }
  24. return -1
  25. }
  26. func main() {
  27. fmt.Println(search([]int{4,5,6,7,0,1,2},0))
  28. }

image.png