LeetCode- Search in Rotated Sorted Array旋转有序数组查找目标数

题目:33Search in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

题目解释:假设一个有序数组被旋转,你有一个目标数去在这个数组中查找它的位置,找不到返回-1.

附加条件:假设这个有序数组没有重复元素。

LeetCode的题目网上大家分享的题解有非常多,我也就是将解答代码记录下来以供自己更为理解。


1、首先我们理解题目条件:①有序数组 ②以某点为原点旋转

有序数组我们一般第一反应是二分法查找,而旋转的数组的特点还是局部有序。只是以原始数组第一位置为分割点左右子数组分别有序。如下的数组中:

4 5 6 7 0 1 2
0就是一个分割点。我们就需要利用局部有序的优点。

首先,得到当前数组的中间点mid,

1、如果该点值arr[mid]=target,那就最好不过了,直接返回该点的索引;

2、否则找到左右两边哪个是局部有序的,进行排除法查找,①若左边有序子数组,则arr[start]<=arr[mid],那么久判断target是否居于arr[start]和arr[mid]值之间,如果是,则整个查找数组缩小为左边数组范围,即将end=mid,接下来的查找范围为[start,mid]规模缩小一半的数组。②左边若不是有序,那么右边必然有序,则查找target是否在右边,即判断target是否在arr[mid]和arr[end]值之间,如果是那么target就在右边子数组,将start=mid+1(为什么start是mid+1后移一位,而end直接等于mid而不用-1迁移一位呢?这是因为我们计算mid的时候是将(start+end)/2的结果转为int时候截断了可能有的0.5因此mid是靠近start的,因此将mid作为结尾end的时候是不需要前移mid-1的,这个也是我当初比较疑惑的一点,这些边界条件我们必须揪想清楚)。

如果最终也没有碰到arr[mid]==target,那就是整个数组都找不到target,因此返回-1即可。

这样的方法的优点是不用判断数组的情况

arr.size()==0;则start=0;end=-1;则直接不进入循环,直接返回-1;

arr.size()==1;则start=0;end=0;计算出来的mid=0;因此判断arr[mid],也就是唯一的这个元素是否为target,不是的话下面的if条件判断将会start=mid+1,此时start>end,也不能进入下轮循环,退出return -1;

arr.size()>=2,情况就以此类推

代码如下:

class Solution {
public:
    int search(vector<int>& arr, int target) {
    int start = 0,end = arr.size()-1;
	while (start<=end)
	{
		int mid = start + (end - start) / 2;
		if (target == arr[mid]) return mid;
		if(arr[start]<=arr[mid])
		{
			if (arr[start] <= target&&target < arr[mid])
				end = mid;
			else
				start = mid + 1;
		}
		else
		{
			if (arr[mid] < target&&target <= arr[end])
				start = mid + 1;
			else
				end = mid;
		}
	}
	return -1;
    }
};





猜你喜欢

转载自blog.csdn.net/qq_18548149/article/details/79549929