题目地址:Search in Rotated Sorted Array
题目简介:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组[0,1,2,4,5,6,7]可能变为[4,5,6,7,0,1,2])。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回-1。要求算法的时间复杂度为O(logn)级别。
题目解析:
看到时间复杂度的要求,应该可以看出二分的思想。分析给的例子中[4,5,6,7,0,1,2],如果正常的升序,应该是右边的数字大于左边的数字。那么根据二分的思想,每次应该查看数组的中间值,需要有几点注意的是
- 假如中间位置的值比第一个的数值大,说明从第一个值到中间位置的值之间的顺序是正常的升序,只要目标值在第一个数和中间位置值的区间之内,那么说明目标值在这个区间内。于是可以将数组的右边更新为当前中间的位置,直到找到目标值;
- 假如中间位置的值比最后一个数值小,同上;
C++代码:
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 (nums[mid] == target)
return mid;
else if (nums[mid] < nums[right])
{
if (nums[mid] < target && nums[right] >= target)
left = mid + 1;
else
right = mid - 1;
}
else
{
if (nums[left] <= target && nums[mid] > target)
right = mid - 1;
else
left = mid + 1;
}
}
return -1;
}
};
Python代码:
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = int(left + (right - left) / 2)
if nums[mid] == target:
return mid
elif (nums[mid] < nums[right]):
if (nums[mid] < target and nums[right] >= target):
left = mid + 1
else:
right = mid - 1
else:
if nums[left] <= target and nums[mid] > target:
right = mid - 1
else:
left = mid + 1
return -1