(本博客旨在個人總結回顧)
題目描述:
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如數組{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;
}
運行結果: