码迷,mamicode.com
首页 > 编程语言 > 详细

剑指offer面试题8——旋转数组的最小数字

时间:2015-06-30 21:43:54      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:

题目1386:旋转数组的最小数字

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:6708

解决:1505

题目描述:

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

 

输入:

输入可能包含多个测试样例,对于每个测试案例,

输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数。

输入的第二行包括n个整数,其中每个整数a的范围是(1<=a<=10000000)。

 

输出:

对应每个测试案例,

输出旋转数组中最小的元素。

 

样例输入:
5
3 4 5 1 2
样例输出:
1

二分查找

   查找某个数

这里考察二分查找一个旋转的数组3 4 5 1 2 .

我自己的想法是,直接采用二分法,将mid=(start+end)/2,有两种情况,1.vec[start]<vec[end],前面一个还是递增,所以直接用二分法,后面一个再递归.但是这个方法的缺点是不能存在有相同的数子

当相同的数字存在时,只能采用顺序的查找了

 

查找最小数

和上面的方法差不多.

#include <iostream>
#include<vector>
using namespace std;

//常规的对顺序数组的二分查找某个值
int banry_search(vector<int>& vec,int va,int st,int en)
{
	if(vec.empty())
		return -1;
	if(st==en)
	{
		if(vec[st]==va)
			return st;
		else
			return -1;
	}
	if(st+1==en)
	{
		if(vec[st]==va)
			return st;
		if(vec[en]==va)
			return en;
		return -1;
	}
	int mid=(st+en)/2;
	return banry_search(vec,va,st,mid-1);
	return banry_search(vec,va,mid+1,en);
}

//对旋转数组的二分查找某个值
int search(vector<int>& vec,int va,int st,int en)
{
	if(vec.empty())
		return -1;
	if(st==en)
	{
		if(vec[st]==va)
			return st;
		else
			return -1;
	}
	if(st+1==en)
	{
		if(vec[st]==va)
			return st;
		if(vec[en]==va)
			return en;
		return -1;
	}
	int mid=(st+en)/2;

	if(vec[st]<vec[mid])
	{
		int re;
		re=banry_search(vec,va,st,mid);
		if(re!=-1)
			return re;
		else
			return search(vec,va,mid+1,en);
	}
	else
	{
		int re;
		re=banry_search(vec,va,mid+1,en);
		if(re!=-1)
			return re;
		else
			return search(vec,va,st,mid);
	}
}


//在旋转数组中查找最小值的函数--3,4,5,1,2
//这里面已经假设了没有存在相同的数字
int search2(vector<int>& vec)
{
	if(vec.empty())
		return -1;
	int len=vec.size();
	int p1,p2;
	p1=0;
	p2=len-1;
	while(1)
	{
		if(p1==p2)
			return vec[p1];
		if(p1+1==p2)
			return vec[p1]>vec[p2]?vec[p2]:vec[p1];
		int tem=(p1+p2)/2;
		if(vec[tem]>vec[p1])
			p1=tem;
		else
			p2=tem;
	}
}

//在旋转数组中查找最小值的函数--1,1,1,0,1
//这里面已经假设了存在相同的数字
//当存在相同的数组时只能顺序的查找了
int search3(vector<int>& vec)
{
	if(vec.empty())
		return -1;
	int len=vec.size();
	int p1,p2;
	p1=0;
	p2=len-1;
	while(1)
	{
		if(p1==p2)
			return vec[p1];
		if(p1+1==p2)
			return vec[p1]>vec[p2]?vec[p2]:vec[p1];
		int tem=(p1+p2)/2;
		if(vec[tem]>vec[p1])
			p1=tem;
		else if(vec[tem]<vec[p1])
			p2=tem;
		else
		{
			int re=vec[p1];
			for(int i=p1;i<=p2;i++)
				if(vec[i]<=re)
					re=vec[i];
			return re;
		}
	}
}

int main()
{
	int ary[5]={1,1,1,0,1};
	vector<int> vec(ary,ary+5);
	cout<<search3(vec)<<endl;
}

  

剑指offer面试题8——旋转数组的最小数字

标签:

原文地址:http://www.cnblogs.com/yanliang12138/p/4611576.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!