面试题8:数组的旋转

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素。例如输入{1,2,3,4,5}的一个旋转为{3,4,5,1,2},该数组的最小值为1。


算法思路:因为数组是递增的,旋转后分为两部分,两部分都是有序的,可以利用二分查找的思想,记录最左边的元素left、中间元素mid和最右边的元素right,首先判断左边值是否大于或等于右边的如果成立判断right-left是否等于1,如果等于一说明最小的值位于right直接返回,如果不等于计算mid,判断a[left]和a[mid],如果小于或等于mid,说明最小值在mid之后让left的值等于mid,如果大于则继续向下执行判断a[right]和a[mid],如果mid小于或等于right,说明最小值位于right之前,将right设为mid向前开始查找,循环结束条件是right-left等于1。

特殊情况:如果左边的数和中间的数以及右边的数相等则按顺序查找.如{1,1,1,1,1}.


代码(C++):

#include <iostream>
using namespace std;

int minNumInRotateArray(int array[],int length);
int MinInOrder(int array[],int left,int right);

int mian()
{
	int a1[]={3,4,5,1,2};
	int a2[]={1,1,1,0,1};
	int length=sizeof(a1)/sizeof(int);
    int result=minNumInRotateArray(a1,length);
	cout<<result<<endl;
	return 0;
}


int minNumInRotateArray(int array[],int length)
{
	if(array==NULL||length<0)
	{
		throw new exception("Invalid parameters");
	}
	int left=0;
	int right=length-1;
	int mid=0;
	while(array[left]>=array[right])
	{
		if(right-left==1)
		{
			return array[right];
		}

		mid=(left+right)/2;
			
		//如果左边的数和中间的数以及右边的数相等则按顺序查找
		if(array[left]==array[right]&&array[mid]==array[left])
		{
			return MinInOrder(array,left,right);
		}
		//如果中间数大于最左边的数,说明最小值在中间数的右边
		if(array[mid]>=array[left])
		{
			left=mid;
		}
		if(array[mid]<=array[right])
		{
			right=mid;
		}
	}
	return array[mid];
}
/*按顺序从left到right查找找出最小的值返回*/
int MinInOrder(int array[],int left,int right)
{
	int result=array[left];
	for(int i=left;i<=right;i++)
	{
		if(result>array[i])
		{
			result=array[i];
		}
	}
	return result;
}


代码(Java):

	public static void main(String[] args) {
		int array[]={1,1,1,1,1};
		System.out.println(minNumInRotateArray(array,array.length));
		
	}
	
	public static int minNumInRotateArray(int array[],int length)
	{
		int left=0;
		int right=length-1;
		int mid=0;
		while(array[left]>=array[right])
		{
			if(right-left==1)
			{
				return array[right];
			}

			mid=(left+right)/2;
			
			//如果左边的数和中间的数以及右边的数相等则按顺序查找
			if(array[left]==array[right]&&array[mid]==array[left])
			{
				return MinInOrder(array,left,right);
			}
			//如果中间数大于最左边的数,说明最小值在中间数的右边
			if(array[mid]>=array[left])
			{
				left=mid;
			}
			if(array[mid]<=array[right])
			{
				right=mid;
			}
		}
		return array[mid];
	}
	
	public static int MinInOrder(int array[],int left,int right)
	{
		int result=array[left];
		for(int i=left;i<=right;i++)
		{
			if(result>array[i])
			{
				result=array[i];
			}
		}
		return result;
	<span style="font-family: Arial, Helvetica, sans-serif;">}</span>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值