题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。
思路:设两个指针p1,p2,p1指向首元素,p2指向最尾,让p1一直在前面递增的数组中,p2在后面递增的数组中。然后查找中间数,与首元素和尾元素进行比较。有如下几种情况:
1.中间数 > 首元素。[3,4,5,1,2],p1指3,p2指2,中间数指5,5大于3,所以最小数肯定在5后面,且5位于前面这个递增数组中,所以移动p1指向5。
2.中间数 < 首元素。然后5和2的中间数为1,1小于2,所以1在后面的递增数组中,所以移动p2到1。此时p1和p2距离1,所以p1指向第一个递增数组的末尾,p2指向第二个递增数组的开头,,所以p2指的为该数组的最小值。
3.尾元素 > 首元素。这该数组一定为递增数组,无须变动,直接返回第一个元素。
4.首元素 = 尾元素 = 中间元素。此时应用顺序查找。
测试用例:
1.功能测试(输入的数组是升序排序数组的一个旋转,数组中有重复数字或者没有重复数字)。
2.边界值测试(输入的数组是一个升序排序的数组、只包含一个数字的数组)。
3.特殊输入册数(输入NULL指针)。
时间复杂度:顺序查找:O(n),二分法查找:O(logn)。
代码:
#include<iostream>
using namespace std;
int MinInOrder(int* numbers, int index1, int index2)
{
int result = numbers[index1];
for (int i = index1 + 1; i <= index2; ++i)
{
if (result > numbers[i])
{
result = numbers[i];
}
}
return result;
}
int Min(int* numbers, int length)
{
if (numbers == NULL || length <= 0)
{
cout << "无效输入" << endl;
return 0;
}
int index1 = 0;
int index2 = length - 1;
int indexMid = index1; //indexMid为最小值
while (numbers[index1] >= numbers[index2])
{
if (index2 - index1 == 1)
{
indexMid = index2;
break;
}
indexMid = (index1 + index2) / 2;
//如果下标为index1、index2和indexMid指向的三个数字相等,则顺序查找
if (numbers[index1] == numbers[index2] && numbers[indexMid] == numbers[index1])
{
return MinInOrder(numbers, index1, index2);
}
if (numbers[indexMid] >= numbers[index1])
{
index1 = indexMid;
}
else if (numbers[indexMid] <= numbers[index2])
{
index2 = indexMid;
}
}
return numbers[indexMid];
}
//测试
void test1()
{
int a[5] = {3,4,5,1,2};
int min = Min((int*)a, 5);
if (min == 1)
{
cout << "passed!" << endl;
}
else
{
cout << "failed!" << endl;
}
}
void test2()
{
int a[5] = {1,2,3,4,5};
int min = Min((int*)a, 5);
if (min == 1)
{
cout << "passed!" << endl;
}
else
{
cout << "failed!" << endl;
}
}
void test3()
{
int a[1] = {1};
int min = Min((int*)a, 1);
if (min == 1)
{
cout << "passed!" << endl;
}
else
{
cout << "failed!" << endl;
}
}
void test4()
{
int min = Min(NULL, 1);
}
int main()
{
test1();
test2();
test3();
test4();
return 0;
}