您的位置:首页 > 其它

8+查找一个旋转数组的最小元素

2015-08-26 20:22 447 查看
title:

查找一个旋转数组a中的最小元素(首尾下标:start,end)

旋转数组就是将一个有序数组的前n个元素移到数组的尾部,形成类似bitonic序列

(先递增再递减或者先递减再递增)的数组

thought:

方法:采用二分查找的方法(O(logn)),

当中间值不小于第一个元素,则最小元素在中间值后面;

当中间值不大于最末元素,则最大值在中间值前面(均包含中间值在内)

特例1:旋转数组仍是有序数组,即将原来数组中的前“0”个元素移到数组尾部

特例2: 当中间值与首位和末位元素三者相等时,判断不出最小元素在中间值之前还是之后,

此种情况下只能采用顺序查找的方法

realize:(以递增数组为例)

1、先设置中间元素下标mid=start(处理特例1)

2、以a[start] >= a[end]为while循环条件:

{

如果首尾下标相邻或者相等,则mid就等于end,循环结束,返回a[mid];

计算mid=(start +end)/2

如果首尾元素和中间元素三者相等,则转向顺序查找函数来查找最小值

如果a[mid] >= a[start],则最小元素在mid后面(包括mid)的序列,即start=mid

如果a[mid] <= a[end],则最小元素在mid前面(包括mid)的序列,即end=mid

}

3、返回a[mid]

#include <iostream>
#include <iomanip>
using namespace std;
int find_min(int [],int Len);
int find_min_inorder(int [],int start,int end);  //顺序查找

int find_min(int a[],int Len)
{
if(NULL == a || Len <= 0)
throw new std::exception("Invaild array!");
int  start = 0;
int  end = Len-1;
int mid = start;  //把中间元素初始化为首位元素是为了处理一个“特例”:把原递增数组的前“0”个元素移到末位(说明旋转数组仍然是递增数组))
while (a[start] >= a[end])
{
if(end-start <= 1)
{
mid = end;
break;
}
mid = (start +end)/2;
if(a[start] == a[mid] && a[mid] == a[end])
return find_min_inorder(a,start,end);
if(a[mid] >= a[start])
start = mid;
else if(a[mid] <= a[end])
end = mid;
}
return a[mid];
}

int find_min_inorder(int a[],int start,int end)
{
int Min = a[start];
for(int i = start;i <= end;i++)
{
if(a[i] < Min)
Min = a[i];
}
return Min;
}

int main()
{
int array_roate[] = {3,4,5,6,1,2,3};
//int array_roate[] = {1,0,1,1,1};  //特例:中间元素和首尾元素三者相等(只能采用顺序查找的方法)
//int array_roate[] = {1,2,3,4,5};  //旋转数组仍为顺序数组(需要将mid初始化为首位元素)
int length = sizeof(array_roate)/sizeof(int);
cout << "旋转数组如下:" << endl;
for(int i = 0;i < length;i++)
cout << setw(3) << array_roate[i];
cout << endl;
int Min = find_min(array_roate,length);
cout << "旋转数组中的最小元素是:" << Min << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: