(本博客旨在个人总结回顾)
题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1 2}为{1, 2,3,4,5}的一个旋转,该数组的最小值为1。
分析:
①从头遍历就可以得到最小值,时间复杂度为O(n),而题目给的信息就根本没用到,肯定满足不了面试官 ·~_~||
②在算法的面试小提示,这题可以尝试使用二分查找去解决。
// OfferMemo8.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
/*
* @name FindMin
* @brief 二分法查找数组最小值
* @param [in] int * pArray 有序递增数组的旋转数组
* @param [in] int nLength 数组长度
* @param [in] int nMid 转入保存搜索结果的引用
* @return bool
*/
bool FindMin(int* pArray, int nLength, int& nMin)
{
if (NULL == pArray || nLength <= 0)
{
return false;
}
int nLeft = 0;
int nRight = nLength - 1;
int nMid = -1;
//判断是否为有序序列
if (pArray[nLeft] < pArray[nRight])
{
nMin = pArray[nLeft];
return true;
}
while (nLeft < nRight - 1)
{
//除去两端相等,左边重复在值
while (pArray[nLeft] == pArray[nRight] && nLeft < nRight - 1)
{
nLeft++;
}
nMid = (nLeft + nRight) / 2;
if (pArray[nLeft] > pArray[nRight])
{
if (pArray[nLeft] > pArray[nMid])
{
nRight = nMid;
}
else
{
nLeft = nMid;
}
}
else
{
nMin = pArray[nLeft];
return true;
}
}
nMin = pArray[nLeft] < pArray[nRight] ? pArray[nLeft] : pArray[nRight];
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
//测试数据
//int a[] = {3, 4, 5, 1, 2};
//int a[] = {1, 2, 3, 4, 5};
int a[] = {2, 2, 2, 2, 2, 2, 1, 2, 2};
//int a[] = {2};
//int a[] = {2, 2, 2, 2, 2};
int nLength = sizeof(a) / sizeof(a[0]);
int nMin = 0;
cout << "旋转的数组:" << endl;
for (int i = 0; i < nLength; i++)
{
cout << a[i] << " ";
}
bool bRet = FindMin(a, nLength, nMin);
if (bRet)
{
cout << endl << "最小值:" << nMin << endl;
}
else
{
cout << endl << "调用查找函数失败!" << endl;
}
system("pause");
return 0;
}
运行结果: