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

题目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;
}

  

时间: 2024-10-08 01:58:26

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

《剑指Offer》算法题——“旋转数组”的最小数字

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减序列的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. //这里说的非递减并不是乱序的,也是递增的,只不过递增的过程中可以有相同数字而已 #include <iostream> #include <vector> using namespace std; class Solution { public: int minNu

剑指offer(6)旋转数组的最小数字

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 解题代码: function minNumberInRotateArray(rotateArray) { // write code here if(rotateArray.length == 0){ retu

剑指offer 面试题33 把数组排成最小的数

题目链接: 剑指offer 题目链接: 把数组排成最小的数, 例如{3, 32, 321} 输出: 321323 解题思路: 我现在已经知道正确答案了, 就是没有办法去证明, 先去开会, 在开会的时候再去想. 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iterator&g

剑指offer 面试题33—把数组排成最小的数

题目: 输入一个正整数数组,把数组里面的所有数字连接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3, 32,  321},则打印这三个数字能排成的最小数字321323. 基本思想:O(nlogn) 两个数字m和n能拼接数字mn和nm.如果mn<nm,那么我们应该打印出mn,也就是m应该排在n的前面,我们定义此时m小于n:反之,如果nm<mn,我们定义n小于m.如果mn=nm,m等于n. 如对321和32,排序为32132<32321,所以321<32(这个小于

【剑指offer】面试题 11. 旋转数组的最小数字

面试题 11. 旋转数组的最小数字 题目描述 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转, 输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 解答 复杂度:O(logN) + O(1) public class Solution { public int minNumberInRotateArray(int

剑指Offer 面试题36:数组中的逆序对及其变形(Leetcode 315. Count of Smaller Numbers After Self)题解

剑指Offer 面试题36:数组中的逆序对 题目:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 例如, 在数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6),(7,5),(7,4),(6,4)和(5,4),输出5. 提交网址: http://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188 或 htt

剑指offer面试题29:数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过数组长度的一般,请找出这个数字,例如输入一个长度为9的数组(1,2,3,2,2,2,5,4,2,).由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 个人第一眼想法是通过一个sort函数,再判断中间那数出现次数,只要出现多于n/2,就直接输出. 一般来说,最为直观的算法面试官都不会满意,那么有没有更优的算法呢? 这种算法是受快速排序算法的启发.在随机快速排序算法中,我们现在数组中随机选择一个数字,然后调整数组中数字的顺序,使得比选中的数字小的数字

【剑指Offer学习】【面试题8 : 旋转数组的最小数字】

题目: 把一个数组最开始的若干个元素搬到数组的末尾, 我们称之数组的旋转.输入一个递增排序的数组的一个旋转, 输出旋转数组的最小元素.例如数组{3,4, 5, 1, 2 }为{ l1,2,3, 4,5}的一个旋转,该数组的最小值为1 实现代码如下: public class Test08 { /** * 把一个数组最开始的若干个元素搬到数组的末尾, 我们称之数组的旋转. * 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素. * 例如数组{3, 4, 5, 1, 2}为{l ,2, 3,

面试题08_旋转数组的最小数字——剑指offer系列

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素. 例如:数组{3, 4, 5, 1 , 2} 是 数组{1,2,3,4,5}的一个旋转,该数组最小的数是1. 我们要做的就是找到这个旋转后数组的最小数. 解题思路: 思路1:直接遍历数组,找到最小的数,简单粗暴,时间复杂度O(n),空间复杂度O(1). 一般情况下,能够做到思路一的时空复杂度就很好了,但是这个题目,还可以有更好的思路,将时间复杂度降低. 思路2: