1:Leetcode_33. Search 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.
Your algorithm’s runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
题目意思:就是用O(n)的时间复杂度在一个旋转了的有序数组中找到target值。
解析:这个题目我觉得挺难得。
首先看[0,1,2,4,5,6,7]的变形
[7,0,1,2,4,5,6]
[6,7,0,1,2,4,5]
[5,6,7,0,1,2,4]
[4,5,6,7,0,1,2]
[2,4,5,6,7,0,1]
[1,2,4,5,6,7,0]
class Solution {
public:
int search(vector<int>& nums, int target)
{
if(nums.size()==0) return -1;
int l = 0;
int r = nums.size()-1;
while(l<=r)
{
int mid = (l+r)>>1;
if(nums[mid]==target) return mid;
else if(nums[mid]<nums[r])
{
if(nums[mid]<target&&nums[r]>=target) l = mid+1;
else r = mid-1;
}
else
{
if(target>=nums[l]&&nums[mid]>target) r = mid-1;
else l = mid+1;
}
}
return -1;
}
};
2:旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
这个最简单的方法当然是从头到尾进行遍历,时间复杂度为O(n),但是效率比较低。
另外一种方法就是二分,首先数组进行旋转以后,前后分成了两个有序的序列,例如 3,4,5,1,2,那么我们可以利用二分
。
首先将left = 0,right = size-1,
那么算出mid的值,如果array[mid]>=array[left],那么说明还处于前面那个有序数组中,这时候可以将left = mid,但是如果array[mid]<array[right],那么说明处于后面那个有序数组中,可以将right = mid,最后结束的条件是 left只想前面有序数组的最后一个元素,而right只想第二个有序数组的第一个元素。即left = right-1。但是也有特殊情况:
1:如果数组没有旋转,即为原样,即1,2,3,4,5.则最开始array[left]>=array[right]不成立,那么直接返回array[0]即可。
2:如果array[left],array[mid],array[right],所指的值都一样,那么必须从头到尾遍历。举例,
1,1,1,0,1 ,array[left] = 1,array[mid] = 1,array[4] = 1,不知道到底哪个是处于有序的序列中,这时候只能遍历整个数组才行。
代码:
class Solution
{
public:
int in_order(vector<int>rotateArray)
{
int min_value = rotateArray[0];
int len = rotateArray.size();
for(int i=1;i<len;i++)
{
if(rotateArray[i]<min_value) min_value = rotateArray[i];
}
return min_value;
}
int minNumberInRotateArray(vector<int>rotateArray)
{
if(rotateArray.size()==0) return 0;
int size = rotateArray.size();
int l = 0 ,r = size-1;
int mid = 0;
while(rotateArray[l]>=rotateArray[r])
{
if(r-l==1)
{
mid = r;
break;
}
int mid = (l+r)>>1;
if(rotateArray[l]==rotateArray[mid]&&rotateArray[r]==rotateArray[mid]) return in_order(rotateArray);
if(rotateArray[mid]>=rotateArray[l]) l = mid;
else r = mid;
}
return rotateArray[mid];
}
};