1 题目描述
假定一个按升序排好的数组在您预先不可知的某个支点被旋转了。如[0,1,2,4,5,6,7]被旋转为了[4,5,6,7,0,1,2])。 给您一个目标值来搜索,若在数组中找到了,返回其标号,否则返回-1。您可以假定该数组中元素没有重复。您的运行时复杂度须为O(log n)。
例子1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
例子2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
题目出处:LeetCode
2 解决思路
总体思路还是折半查找,判断数组的两种情况:
1)标准升序数组(头值小于等于尾值),直接折半查找;
2)被旋转的升序数组(头值大于尾值),判断的情形可能会多一点;
2.1)若目标值大于等于头值;
2.1.1)若mid值比头值大且目标值大于mid值,去后半部分查找;
2.1.1)若mid值比头值小,去前半部分查找;
2.2)若目标值小于头值;
2.2.1)若mid值比头值大,mid之前的部分可以排除了,去后半部分查找;
2.2.2)若mid值比头值小,判断目标值若比mid值还小,则去排除头值的左半部分查找;否则去后半部分查找。
3 Golang实现代码
https://github.com/leileiluoluo/
func search(nums []int, target int) int {
start := 0
end := len(nums) - 1
for start <= end {
mid := (start + end) / 2
if target == nums[mid] {
return mid
}
if nums[start] <= nums[end] {
if target < nums[mid] {
end = mid - 1
} else {
start = mid + 1
}
} else {
if target >= nums[start] {
if nums[mid] >= nums[start] &&
target > nums[mid] {
start = mid + 1
} else {
end = mid - 1
}
} else {
if nums[mid] >= nums[start] {
start = mid + 1
} else {
if target < nums[mid] {
start++
end = mid - 1
} else {
start = mid + 1
}
}
}
}
}
return -1
}