【34】旋转数组的最小数字

题目:把一个递增数组的前几个元素移动到数组的末尾,我们称之为数组的旋转。输入一个递增排序数组的旋转,输出旋转数组的最小元素。例如输入3 4 5 6 7 1 2,则最小元素为1。规定递增元素是没有重复元素的。

分析:

1. 最简单做法是从头到尾遍历数组,就可以求出最小元素。时间复杂度O(n),但是这个是最朴素的方法。

2. 根据旋转数组的性质,旋转数组满足“递增-最小值-递增”的性质。利用这个性质我们可以比较快速的求出最小元素。例如3 4 5 6 7 - 1 - 2,就是满足递增-最小值-递增

    具体的做法是设置两个指针p1和p2,初始化分别指向数组的头和尾,然后比较两个指针所指的值和两个指针中间位置的值的关系。mid = (p1+p2) >> 1;

   (1)如果arr[mid] > arr[p2],说明最小元素在mid之后则p1 = mid

   (2)如果arr[mid]  < arr[p2],说明最小元素在mid之前则p2 = mid

   (3)如果两个指针相差为1的时候,最小值即为最小元素

    时间复杂度为O(logn),因为每次可以跳到中间位置,类似二分搜索。

 

3. 举例旋转数组3 4 5 6 7 1 2

    第一次p1指向3,p2指向2,mid指向6,发现arr[mid] > arr[p2]说明最小元素在mid之后,则p1 = mid

    第二次p1指向6,p2指向2,mid指向7,发现arr[mid] > arr[p2]说明最小元素在mid之后,则p1 = mid

    第三次p1指向7,p2指向2,mid指向1,发现arr[mid] < arr[p2]说明最小元素在mid之前,则p2 = mid

    第四次p1指向7,p2指向1,此时p1和p2差1,则最小元素为1.

4. 代码

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

//求最小元素
int GetMinNum(int *arrNum, int n){
	//不合法数据
	if(arrNum == NULL || n <= 0){
        return -1;
    }
	int left = 0;
	int right = n-1;
	while(left < right){
        if(right == left+1){
            return min(arrNum[left], arrNum[right]);
        }
		int mid = (left+right)>>1;
        if(arrNum[mid] > arrNum[right]){
            left = mid;
        }
        else{
	        right = mid;
        }
	}
} 

int main(){
    int arrNum[] = {3,4,5,6,7,1,2};
    int value = GetMinNum(arrNum, 7);
    cout<<value<<endl; //输出1
    return 0;
}
时间: 2024-10-01 08:33:08

【34】旋转数组的最小数字的相关文章

[剑指Offer]10.旋转数组的最小数字

题目1386:旋转数组的最小数字 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数. 输入的第二行包括n个整数,其中每个整数a的范围是(1<=a<=10000000). 输出:

《剑指offer》-旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 考察二分查找.虽然是有序数组进行了旋转的,但实际上依然可以用二分的做法来找. int minNumberInRotateArray(vector<int> rotateArray){ int low = 0; int

[经典面试题]输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。

[题目] 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1. [分析] 这道题最直观的解法并不难.从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N).但这个思路没有利用输入数组的特性,我们应该能找到更好的解法.  我们注意到旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后

如何把数组排成最小的数

题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数. 输入的第二行包括m个正整数,其中每个正整数不超过10000000. 输出: 对应每个测试案例, 输出m个数字能排成的最小数字. 样例输入:323 13 6223456 56样例输

剑指offer系列之三十一:把数组排成最小的数

题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 根据结果判断,所谓最小的数字实际上就是对数组中所有元素的一个组合.一种笨拙的方法是求出所有元素的全排列,然后对所有排列的值的大小进行排序,那么就可以得到最小的数了.求全排列的算法已经在之前的文章中提到.那么是不是还有其他思路呢?联想到Java库函数中有一个sort方法,是不是可以直接使用呢?(该sort方法的时

怎样在Excel中计算比某个固定数大的最小数字

  ①启动Excel,小编是2007版本,打开先前我准备好了的源数据表格.A.B.C列分别为地区.销售人员.数据,我们要算出数据中大于80的且最小的值. ②在E2输入公式,=large(C2:C13,countif(C2:C13,">80")),记住公式要是在英文半角状态下输入. 计算比某个固定数大的最小数字-行距最小值和固定值"> ③回车,得到结果81,对照源表格,查看到第5行数据是81,是我们想要的结果. 公式说明 首先,Countif函数会统计出大于80的一

c#-C#中对数组中的数字取绝对值

问题描述 C#中对数组中的数字取绝对值 fpt_ChiJu = Math.Abs(arrX).Max(); 这是我编写的程序,想实现对数组arrX中的每个数字取绝对值,完了之后再取最大值,可是运行之后报错了,,求解答! 解决方案 fpt_ChiJu = arrX.Select(x => Math.Abs(x)).Max();

ruby 怎么利用正则表达式在把一个字符串数组中的数字放到一个数组中?

问题描述 ruby 怎么利用正则表达式在把一个字符串数组中的数字放到一个数组中?str='100good200bad300ok'问题补充:说错了是把一个字符串中的所有数字放到一个数组中:)问题补充:是 100 200 300不过还是谢谢sunfjun 解决方案 str='100good200bad300ok' str.scan(/d+/)解决方案二:String的这个scan方法真不错, shaquan6776解决方案三:'100good200bad300ok'.split(/[^d]/).re

求和-如何将两个字符数组里的数字相加得出两组数的和

问题描述 如何将两个字符数组里的数字相加得出两组数的和 char a[1000],b[1000] 两个数组里都是数字 解决方案 void Add(char a[],char b[],char d[]) { char c[10001]; int lena=strlen(a),lenb=strlen(b); int i,j,len; len=lena>lenb?lena:lenb; len++; c[0]=''; for(i=1;i<=len;i++)c[i]='0'; for(i=1;i<