面试题11:旋转数组的最小数字
题目1:把一个数组的若干元素搬到数组末尾,我们称之为数组的旋转。输入一个递增的数组的旋转,输出数组中的最小元素。
思路
- 暴力遍历 时间o(n)
- 二分查找最小的数 时间o(logn)
#include "stdafx.h"
#include <exception>
int FindMinNum(int *data, int length)
{
if (data == nullptr || length <= 0)
throw std::exception("Invalid Parameter!");
int start = 0;
int end = length - 1;
int midIndex = 0;
if (data[end] > data[start])
return data[start];
while ((end-start)>1)
{
midIndex = (start + end) / 2;
if (data[midIndex] > data[start])
start = midIndex;
else if (data[midIndex] < data[end])
end = midIndex;
}
return data[end];
}
题目1:把一个数组的若干元素搬到数组末尾,我们称之为数组的旋转。输入一个递增的数组的旋转而且数组中有重复的元素,输出数组中的最小元素。
思路
- 暴力遍历 时间o(n)
- 二分查找最小的数 时间o(logn) 一,当遇到mid、start、end都相等的情况直接改用遍历。二、或者在当data[mid]==data[end]时让end–,到小于当前值的那个位置继续遍历。
int FindMinNum(int *data, int length)
{
if (data == nullptr || length <= 0)
throw std::exception("Invalid Parameter!");
int start = 0;
int end = length - 1;
int midIndex = 0;
if (data[end] > data[start])
return data[start];
while ((end - start) > 1)
{
midIndex = (start + end) / 2;
if (data[midIndex] > data[end])
start = midIndex;
else if (data[midIndex] < data[end])
end = midIndex;
else
end--;
}
return data[end];
}
测试代码
// ====================测试代码====================
void Test(int* numbers, int length, int expected)
{
int result = 0;
try
{
result = FindMinNum(numbers, length);
for (int i = 0; i < length; ++i)
printf("%d ", numbers[i]);
if (result == expected)
printf("\tpassed\n");
else
printf("\tfailed\n");
}
catch (...)
{
if (numbers == nullptr)
printf("Test passed.\n");
else
printf("Test failed.\n");
}
}
int main(int argc, char* argv[])
{
// 典型输入,单调升序的数组的一个旋转
int array1[] = { 3, 4, 5, 1, 2 };
Test(array1, sizeof(array1) / sizeof(int), 1);
// 有重复数字,并且重复的数字刚好的最小的数字
int array2[] = { 3, 4, 5, 1, 1, 2 };
Test(array2, sizeof(array2) / sizeof(int), 1);
// 有重复数字,但重复的数字不是第一个数字和最后一个数字
int array3[] = { 3, 4, 5, 1, 2, 2 };
Test(array3, sizeof(array3) / sizeof(int), 1);
// 有重复的数字,并且重复的数字刚好是第一个数字和最后一个数字
int array4[] = { 1, 0, 1, 1, 1 };
Test(array4, sizeof(array4) / sizeof(int), 0);
// 单调升序数组,旋转0个元素,也就是单调升序数组本身
int array5[] = { 1, 2, 3, 4, 5 };
Test(array5, sizeof(array5) / sizeof(int), 1);
// 数组中只有一个数字
int array6[] = { 2 };
Test(array6, sizeof(array6) / sizeof(int), 2);
// 输入nullptr
Test(nullptr, 0, 0);
return 0;
}