Search in Rotated Sorted Array
对一个有序排列的数组,升序排列,每个数各不相同。将其中前面一部分数据挪到后面变成一个新的数组,给定一个数,求这个数在新数组中的下标。
该数存在则返回下标,否则返回-1。
思路:
首先使用二分查找找到数组中最小的那个数的位置small_index,然后以最小的这个数为轴,可以将该数组划分为两部分,small_index之前的数为升序排列,small_index之后的数也是升序排列,确定目标值target的范围,随后采用传统的二分查找算法即可。
寻找最小的数的下标的思路:
small_index的位置可以划分为在mid左边或者mid的右边。low————— mid———————–high
如果small_index在[low,mid]范围内,必然是nums[mid] < nums[high]
如果small_index在[mid,high]范围内,必然是nums[mid] > nums[high]
以此进行二分查找,low或者high每次只有一个更新,更新值<=1,最终结束的时候必然是low = high,此时low的值即为
small_index。后续就是二分查找。
// nums 是数组
// 确定最小的那个数所在的下标small_index
int low = 0;
int high = nums.size()-1;
while(low<high)
{
int mid = (low+high)/2;
if(nums[mid]>nums[high])// 假若small_index在[low,mid]范围内,那么必然
low = mid+1;
else
high = mid;
}
unsigned small_index = low;
最终代码如下
class Solution {
public:
int search(vector<int>& nums, int target) {
if(nums.size()==0)
return -1;
// 确定最小的那个数所在的下标small_index
int low = 0;
int high = nums.size()-1;
while(low<high)
{
int mid = (low+high)/2;
if(nums[mid]>nums[high])
low = mid+1;
else
high = mid;
}
unsigned small_index = low;
// 确定target的范围,选择二分查找的low和high的范围,再进行二分查找
if(nums[small_index] == target)
return small_index;
if(target> nums[nums.size()-1])
{
low = 0;
high = small_index-1;
}
else if(target<=nums[nums.size()-1])
{
low = small_index;
high = nums.size()-1;
}
while(low<=high)
{
int mid = (low+high)/2;
if(nums[mid] == target)
return mid;
else if(nums[mid]< target)
low = mid+1;
else
high = mid-1;
}
if(high==low)
return low;
else
return -1;
}
};