题目描述:旋转数组是将排好序的数组前半部分旋转至后半部分,例如{3,4,5,1,2}是{1,2,3,4,5}的旋转数组,找出其中最小值。
算法描述:数组data,利用start和end找出其中间值index,通过data[index]和data[start],data[end]的比较,选择将index赋值给start或者end,递归。
代码如下:
#include<iostream>
using namespace std;
int min(int *data,int start,int end)
{
if (data == NULL || (end - start) <=0)
{
throw::exception("arr error!!");
}
if (start < end)
{
return data[start];
}
int index = (end + start) / 2;
if (data[start] == data[end] && data[start] == data[index])
{
return MinInOrder(data, start, end); //顺序查找
}
if (data[index] >= data[start])
{
start = index;
}
if (data[index] < data[end])
{
end = index;
}
if (start != (end - 1))
{
min(data, start, end);
}
else
{
return data[index];
}
}
void main()
{
int data[] = { 3, 4, 5, 1, 2 };
int len = sizeof(data) / sizeof(data[0]);
cout << min(data, 0, len - 1) << endl;
system("pause");
}
后来想想,这个数组还有种情况,当把数组前0个数旋转到最后,那么这个数组本身还是排序的,所以如果start小于end,说明他是排序的,则加上标记1处的代码。
如果数组是{0,1,1,1,1}的旋转数组{1,0,1,1,1}和{1,1,1,0,1}呢,这种情况会导致程序在判断data[index]和data[start],data[end]的大小时,不能确定最小数是在前半数组里还是后半数组里,所以,这种情况只能通过顺序查找来实现。
int MinInOrder(int *data,int start,int end)
{
int min;
if (data == NULL)
{
throw::exception("arr error!!");
}
min = data[start];
for (int i = start + 1; i < (end - start); i++)
{
if (min >= data[i])
{
min = data[i];
}
}
return min;
}
//下面的代码插入上图中
if (data[start] == data[end] && data[start] == data[index]) //如果start,end与index
//处的数相等,则选择顺序查找
{
return MinInOrder(data, start, end);
}