旋转数组中找最小值

概念:

旋转数组就是,将一个排序数组的前n位数挪到数组的后面,我们称之为旋转数组。例如数组{3,4,5,1,2}就是数组{1,2,3,4,5}的一个旋转。

分析:

找出一个数组中最小的数并不难,只需遍历数组即可,但是次方法的时间复杂度为O(n),而且没有利用旋转数组的特性。

解决:

我们注意到旋转后的数组实际上可划分为两个排序的数组,而且前面的子数组的值都要大于或等于后面的子数组的元素。并且最小的元素恰好是是这两个子数组的分界线。所以试着用二分查找法来寻找这个数。

使用两个指针分别指向数组的第一个数和最后一个数,接着求出中间元素,如果中间元素位与前面的递增子数列,那么他应该大于或者等于第一个指针指向的元素,此时将第一个指针指向中间元素,这样就缩小了查找范围,同样依照此原理,可以把end指针也指向中间元素,也可以缩小范围。

如果第一个指针和第二个指针相差为一时,end指针所指向的值就是最小值。


代码如下:

#include<iostream>
using namespace std;
int find_inorder(int *array, int len)
{
	int min = array[0];
	for (int i = 1; i < len; i++)
	{
		if (array[i] < min)
		{
			min = array[i];
		}
	}
	return min;
}
int Find(int *array, int len)
{
	int start = 0;
	int end = len - 1;
	int mid = start;
	while (array[start] >= array[end])
	{
		if (end - start == 1)
		{
			mid = end;
			break;
		}
		int mid = (start + end) / 2;
		if (array[start] == array[mid] && array[start] == array[end])
		{
			return find_inorder(array,len);
		}
		if (array[mid] >= array[start])
		{
			start = mid;
		}
		if (array[mid] <= array[end])
		{
			end = mid;
		}
	}
	return array[mid];
}

int main()
{
	int array[] = {1,0,1,1,1 };
	int len = sizeof(array) / sizeof(array[0]);
	int min = Find(array, len);
	cout << min << endl;
	return 0;
}

注意:

扫描二维码关注公众号,回复: 1740172 查看本文章

需要考虑到一种情况,当第一个元素等于中间元素并且等于最后一个元素,我们无法判断中间元素到底属于哪一个子数组,此时,就需要顺序查找。



猜你喜欢

转载自blog.csdn.net/qq_40340448/article/details/80720183