时间复杂度:O(log n)
解题思路
题目描述中明确要求时间复杂度为O(log n),再结合数组有序,应该马上想到二分查找算法,但问题是我们应该如何去改良二分查找算法来解决该题目呢?
通过观察我们可以发现,旋转后的数组再次升序排列后,数组中会有两个升序区间,那我们应该如何根据这一特点来应用二分查找呢?
我们可以先来尝试直接对nums数组应用二分查找,先判断target与nums[mid]是否相等,若不相等开始下列步骤,此时mid只有两种情况——①位于左侧较大有序区间内,mid右侧部分有序和②位于右侧较小有序区间内,mid左侧部分有序。而这两种情况的判断特征分别为nums[mid]≥nums[low]和nums[mid]≤nums[high](可以找几个例子仔细想想为什么)。当我们可以判断出mid在左右哪个升序区间内后,便可以按照二分查找的方法令target与nums[low]和nums[mid-1]作比较(情况①)或者与nums[mid+1]和nums[high]作比较(情况②)判断target是否在有序区间内,如果是的话那就去继续二分查找有序区间,否则就去二分查找另一个部分有序区间。
语言描述可能会使理解变得更加困难,但必须要记住一句话,那就是每一次二分后都会在mid左右两侧分出一个有序区间和一个部分有序区间,但我们只能在有序区间内判断是否存在target。
AC代码
func search(nums []int, target int) int {
low,high:=0,len(nums)-1
for low<=high{
mid:=(low+high)>>1
if target==nums[mid]{
return mid
}else if nums[mid]>=nums[low]{//mid在左侧升序区间。注意要考虑到mid==low的情况
if target>=nums[low]&&target<nums[mid]{
high=mid-1
}else {
low=mid+1
}
}else{//mid在右侧较小升序区间
if target>nums[mid]&&target<=nums[high]{
low=mid+1
}else{
high=mid-1
}
}
}
return -1
}
感悟
一开始看题就想到了二分查找,但没想通如何去用二分查找,看了题解后瞬间明白了具体用法。