题意理解
给定一个排序过,并且被旋转过的数组,(意味着有两个递增序列)。查找·指定的数字
问题分析
二分查找
完全排序的序列上的二分查找比较容易。这种部分有序的查找需要追加变化。
这里根据部分有序的特点,在原有的二分查找基础上,对上下半部分的选择,不是简单的和目标数字比大小,而是和上下端点的值比大小。这里比大小的方法是如果中间值比头节点值大,说明前半部分有序,如果target在前半部分,也就是target值小于mid值大于low值,移到左半部分查找;否则移到下部分查找。如果中间值比头节点值小,说明后半部分有序,如过target在后半部分,移到后半部分查找;否则移到上半部分查找。
其他
二分查找的=号是个关键的区分,这个一直没把握好。
210907: 二分查找不一定全有序,部分有序也可以做,能做的原因是,分支判断不需要全条件明确,可以用else包含其他所有情况,而不是穷举所有情况. 然后就是边界值了.
链接
int search(vector<int>& nums, int target) {
int lo = 0, ho = nums.size() - 1; //上下头尾端点值
while(lo <= ho) //二分起手式
{
cout << lo << '\t' << ho << endl;
int mid = (ho + lo) / 2; //求中间点位置
cout << "mid " << mid << endl;
if (nums[mid] == target) return mid; //如果找到,返回下标
if (nums[mid] < nums[lo]) //中间值小于头值
{
//后半部分有序,target落在后半部分
if (target > nums[mid] && target <= nums[ho])
{
lo = mid + 1;
}
else
{
ho = mid - 1;
}
}
else
{
//前半部分有序,target落在前半部分
if (target >= nums[lo] && target < nums[mid])
{
ho = mid - 1;
}
else
{
lo = mid + 1;
}
}
}
return -1;
}