整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为[4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1
思路:
二分查找的实质就是不断缩小区间,关键在于找对缩小区间的条件。
以示例1为例:
nums = [4,5,6,7,0,1,2], target = 0
两个区间【left,mid】和【mid,left】。
首先判断哪个区间是有序的,也就是说
if nums[mid]>=nums[left]{
//说明[left,mid]区间是有序的
}else if nums[mid]<=nums[left]{
//[mid,right]区间是有序的
}
然后判断所要查找的target 是否在此区间内,如果在。则缩小区间为此区间。否则去另外一个区间寻找。
if target<nums[mid] && target>nums[left]{//如果在此区间内
rught = mid - 1
}else {//不在此区间内
left = mid +1
}
target不在【left,mid】区间内。则去【mid,right】区间内继续试探去寻找。
然后循环往复。
总代码:
func search(nums []int, target int) int {
var (
low,high = 0,len(nums)-1
)
for low<=high{
mid:=(low+high)/2
//判断low,mid,high指针是否等于target
if nums[mid]==target{
return mid
}else if nums[low] == target{
return low
}else if nums[high] == target{
return high
}
//[low,mid]区间是否有序
if nums[mid]>=nums[low]{
if target<nums[mid] && target>nums[low]{//target是否在此区间内
high = mid - 1
}else {
low = mid +1
}
}else if nums[mid]<=nums[high]{//[mid,high]区间是否有序
if target>nums[mid]&& target<nums[high]{//target是否在此区间内
low = mid + 1
}else {
high = mid -1
}
}
}
return -1
}