题目
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。
编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true
,否则返回 false
。
示例 1:
输入: nums = [2,5,6,0,0,1,2], target = 0 输出: true
示例 2:
输入: nums = [2,5,6,0,0,1,2], target = 3 输出: false
进阶:
- 这是https://www.cnblogs.com/guohai-stronger/p/12056691.html的延伸题目,本题中的
nums
可能包含重复元素。 - 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?
思想
本题是需要使用二分查找,怎么分是关键,举个例子:
- 第一类
10111 和 11101这种。此种情况下 nums[start] == nums[mid],分不清到底是前面有序还是后面有序,此时 start++ 即可。相当于去掉一个重复的干扰项。
- 第二类
2345671这种,也就是 nums[start] < nums[mid]。此例子中就是 2 < 5;
这种情况下,前半部分有序。因此如果 nums[start] <=target 6712345这种,也就是 nums[start] > nums[mid]。此例子中就是 6 > 2; 这种情况下,后半部分有序。因此如果 nums[mid]
代码
func search(_ nums: [Int], _ target: Int) -> Bool {
if nums.count <= 0 {
return false
}
var start = 0
var end = nums.count - 1
var mid: Int = 0
while start <= end {
mid = start + (end - start)/2
if nums[mid] == target {
return true
}
if nums[start] == nums[mid] {
start += 1
continue
}
if nums[start] <= nums[mid] {
if nums[mid] > target && nums[start] <= target {
end = mid - 1
} else {
start = mid + 1
}
} else {
if nums[mid] < target && nums[end] >= target {
start = mid + 1
} else {
end = mid - 1
}
}
}
return false
}