简单版本:数组中的元素互不相同
LeetCode 33. Search in Rotated Sorted Array
领扣 33. 搜索旋转排序数组
【我的思路】
利用153. Find Minimum in Rotated Sorted Array找到旋转数组最小元素的下标,作为偏移量shift,然后使用普通binary search求解,只不过需要变换坐标
【Discuss的思路】
首先检查target
是否为nums[left]
、nums[mid]
、nums[right]
,如果存在直接返回
由于二分查找只能在有序的数组上进行,所以需要检查数组的前半段(nums[])和后半段哪一段是有序的
情况1:前半段有序,即nums[left] < nums[mid]
成立
1-1:如果target
落在前半段,即nums[left] < target < nums[mid]
(不取等号,因为已经检查过了),则后半部分可以排除,令right = mid - 1
1-2:否则排除前半部分,令left = mid + 1
情况2:否则后半段有序
2-1:如果target
落在后半段,即nums[mid] < target < nums[right]
(不取等号,因为已经检查过了),则前半部分可以排除,令left = mid + 1
2-2:否则排除后半部分,令right = mid - 1
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while( left <= right )
{
int mid = left + ( right - left ) / 2;
if( target == nums[mid] )
return mid;
if( target == nums[left] )
return left;
if( target == nums[right] )
return right;
if( nums[left] < nums[mid] ) // 如果前半段有序
{
if( nums[left] < target && target < nums[mid] )
right = mid - 1;
else
left = mid + 1;
}
else // 否则后半段有序
{
if( nums[mid] < target && target < nums[right] )
left = mid + 1;
else
right = mid - 1;
}
}
return -1;
}
};
困难版本:数组中的元素有重复
Leetcode 81. Search in Rotated Sorted Array II
领扣 81. 搜索旋转排序数组 II
相比于简单版本,仅仅是增加了处理nums[left]
、nums[mid]
和nums[right]
三者相等的情况,处理的方式是left++; right—;
此外,第23行的nums[left] <= nums[mid]
不能缺少等号,如果缺少则WA(暂时没想明白为什么)
class Solution {
public:
bool search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while( left <= right )
{
int mid = left + ( right - left ) / 2;
if( target == nums[mid] )
return true;
if( target == nums[left] )
return true;
if( target == nums[right] )
return true;
// nums[left]、nums[mid]和nums[right]三者相等
if( nums[left] == nums[mid] && nums[mid] == nums[right] )
{
left++;
right--;
}
else if( nums[left] <= nums[mid] ) // 如果前半段有序
{
if( nums[left] < target && target < nums[mid] )
right = mid - 1;
else
left = mid + 1;
}
else // 否则后半段有序
{
if( nums[mid] < target && target < nums[right] )
left = mid + 1;
else
right = mid - 1;
}
}
return false;
}
};