31
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
分析:logn复杂度的查找肯定要用二分查找,本题的问题是不确定待查找的区间是否有序,旋转实质上是将两个有序的区间拼在了一起,所以不难得出如果将整个数组二分,必然存在一个区间是有序的,如果目标在这个有序的区间中,就进一步在这个有序的区间中作二分查找,如果目标不在这个有序的区间中,说明目标只有可能在另一个无序的区间中,而这个无序的区间也必然满足前述的旋转的性质。
class Solution {
public:
int search(vector& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left <= right )
{
int mid = (left + right) / 2;
if(nums[mid] == target) return true;
if(nums[mid] < nums[right])
{
if(target > nums[mid] && target <= nums[right])
{
left = mid + 1;
}else{
right = mid - 1;
}
}else if(nums[mid] > nums[left]){
if(target < nums[mid] && target >= nums[left])
{
right = mid - 1;
} else{
left = mid + 1;
}
}else if(nums[mid] == nums[left]){
left ++;
}else if(nums[mid] == nums[right])
{
right --;
}
}
return false;
}
};
81:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
进阶:
nums
可能包含重复元素。分析: 本题和前一题大体类似,关键在于如何处理这个重复元素,如果沿用前一题的方法,就会出现一些错误。
其中一个错误是 [3 1 1] 查找 3 , 这个时候为什么错呢?因为对当前区间作二分,如果子区间的左右边界恰好相等,这个时候是没有办法判定目标是否在这个区间内,因此当遇到这种情况时,要对左右边界相同的区间作调整。如果当前区间是右子区间,就要将右边界前移直到左右边界不再相同,如果当前区间是左子区间,就要将左边界后移直到左右边界不再相同。
由此可见,如果重复的元素有k个,那么复杂度就会相应的增加o(k) 如果k=n,就到了最坏的情况,整个算法的复杂度为o(n)
class Solution {
public:
int search(vector& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left <= right )
{
int mid = (left + right) / 2;
if(nums[mid] == target) return true;
if(nums[mid] < nums[right])
{
if(target > nums[mid] && target <= nums[right])
{
left = mid + 1;
}else{
right = mid - 1;
}
}else if(nums[mid] > nums[left]){
if(target < nums[mid] && target >= nums[left])
{
right = mid - 1;
} else{
left = mid + 1;
}
}else if(nums[mid] == nums[left]){
left ++;
}else if(nums[mid] == nums[right])
{
right --;
}
}
return false;
}
};