(9)求旋转数组中的最小数值

题目描述:

将一个数组最开始的若干元素搬到数组的末尾,称之为旋转数组;输入一个增序数组的旋转数组例如{3,4,5,1,2} 其旋转数组中的最小数值为{1};


思路一:

顺序遍历数组中的每一个元素,找出最小值;时间复杂度O(n);


思路二:

旋转数组有增序数组变换而来,可以考虑二分查找 , 其复杂度为O(logN);

但是旋转数组的增序排列是分为两部分的,而且我们的目标:最小值,正好为量子数组的分界线;

例如{3 ,4 ,5} ,{1 ,2};分界点:最小值1;

依据二分查找的思想,指针start 指向左边数组的首元素:3 ,指针end 指向右边数组的末尾元素:2

指针middle = (start + end) / 2;

正常情况:

若data[middle] >= data[start]:说明最小值在middle之后,start = middle;

若data[middle] <= data[emd]:说明最小值在middle之前(包括middle) , end = middle; 

当end - start == 1,即start ,end相邻时:minNumber = data[end];

特殊情况:

旋转位数为0;递增数组未翻转;那么此时的最小值 minNumber = data[start]; {1,2,3,4,5}--》{1}

当大部分数组元素相等时:{2 ,1, 2, 2,2,2} , {2 , 2 , 2 , 2 , 1 , 2};

data[start] = data[middle] = data[end];可以在利用顺序遍历的思想;


代码实现:

#include<iostream>
#include<exception>
using  namespace std;
//---------------------------------------------旋转数组的最小数字---------------------------------------
int MinInorder(int* data , int start , int end);

int MinNumber(int* data , int length)
{
	if(data == NULL || length <= 0)
		throw new  std::exception("Invalid parameters");

	int start = 0;
	int end = length - 1;
	//确保旋转位数为0,首部元素最小;
	int middle = start; 

	while(data[start] >= data[end])
	{
		//start end相邻;
		if(end - start == 1)
		{		
			middle = end;
			break;
		}

		middle = (start + end) / 2;

		if(data[middle] >= data[start])  //minNumber 在后半部
			start = middle;
		else if(data[middle] <= data[end]) //minNumber 在前半部
			end = middle;

		//*start ,*middle ,*end 三者相等--》顺序遍历
		if(data[start] == data[middle] && data[middle] == data[end])
			return MinInorder(data , start , end);
	
	}

	return data[middle];
}

//顺序遍历
int MinInorder(int* data , int start , int end)
{
	int minNumber = data[start];
	for(int i = start + 1; i <= end; ++i)
	{
		if(minNumber > data[i])
			minNumber = data[i];
	}

	return minNumber;
}




//---------------------------------------------------------------------------------------------------------------

int main()
{
	
	int data1[] = {3 , 4 , 5 , 1 , 2};
	cout<<MinNumber(data1 , sizeof(data1) / sizeof(int))<<'\n';

	int data2[] = {1 , 2 , 3 , 4 , 5};
	cout<<MinNumber(data2 , sizeof(data2) / sizeof(int))<<'\n';

	int data3[] = {3 , 4 , 5 , 5 , 1 , 2};
	cout<<MinNumber(data3 , sizeof(data3) / sizeof(int))<<'\n';

	int data4[] = {3 , 4 , 5 , 1 , 1 , 2};
	cout<<MinNumber(data4 , sizeof(data4) / sizeof(int))<<'\n';

	int data5[] = {1 , 1 , 1 , 1 , 1 , 1};
	cout<<MinNumber(data5 , sizeof(data5) / sizeof(int))<<'\n';

	cout<<MinNumber(NULL , 0)<<'\n';

	return 0;
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值