求旋转数组的最小数字算法的解析以及完整c语言代码实现

首先了解什么是旋转数组:即把一个数组的最开始的若干个元素搬到数组的末尾,即成为旋转数组,例如数组{3,7,1,8,2}为{1,8,2,3,7}的一个旋转数组。

题目:输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素,例如{1,2,3,4,5}数组的一个旋转数组{3,4,5,1,2},其最小的元素为1,

解析:看到题目以后,我们首先可能会想到遍历这个数组,即可找到最小的元素,时间复杂度为o(n),但是这个思路显然没有利用到数组是递增排序的特性,因此我们得继续寻找更优 的方法,因为原本数组是递增排序的,那么旋转之后的数组是由两个递增排序的数组组成,而且前面的子数组的元素都大于或等于后面子数组的元素,并且这个最小的元素正好将两个子数组分隔,因此我们可以试着用二分查找的思路来查找这个最小元素。

与二分查找方法一样,我们可以用两个指针分别指向这个数组的第一个元素和最后一个元素,按照旋转的规则,第一个元素应该是大于或者等于最后一个元素的,(这其实也不完全对,还有一种情况是特例,稍后讨论),

接着我们可以找到数组中间的元素,如果该数组位于前面的递增子数组,那么他应该大于或者等于第一个指针指向的元素,数组的最小元素应该位于中间元素的后面,因此我们可以将指针指向中间元素,这样就缩小了查找的范围,同理如果中间元素位于后一个递增子数组中,那么他应该小于或等于第二个指针指向的元素,此时该数组中最小的元素应该位于该中间元素的前面,因此我们可以将第二个指针指向该中间元素,缩小查找的范围,

按照上面的思路,第一个指针总是指向前面递增数组的元素,第二个指针指向后面递增数组的元素,最终第一个指针指向前面递增数组的最后一个元素,而第二个指针指向后面子数组的第一个元素,而第二个指针指向的刚好是最小的元素,循环结束。

前面提到的第一个元素应该是大于或等于最后一个元素的,特例:如果把排序数组的前0个元素搬到最后面,即排序数组本身,这仍然是数组的旋转,因此第一个数就是最小的数,我们可以直接返回,

还有一种情况存在即数组{1,0,1,1,1}和数组{1,1,1,0,1}都可以看成是递增排序数组{0,1,1,1,1}的旋转,这样的话第一个元素、中间元素、最后一个元素都是1,我们无法判断中间数字1是属于前面的递增子数组还是第二个递增子数组,因此我们就不可以使用而二分查找的思路解决,只能使用顺序查找的方法。

具体代码如下:

<span style="font-size:24px;">//求旋转数组的最小元素
#include<stdio.h>

int minorder(int a[],int index,int index2);

int min(int *a,int length)
{
	int index,index2,mid;

	if(a==NULL||length<=0)
	   return 0;

     index=0;
	 index2=length-1;
	 mid=index;   //当将前0个元素搬到后面,即排序数组本身,可以直接返回mid

	while(a[index]>=a[index2])
	{
	  if(index2-index==1)       //两个指针指向的元素相邻,即index2指向的元素为最小元素
	  {
		  mid=index2;
          break;
	  }
      mid=(index+index2)/2;
	  if(a[index]==a[index2] && a[mid]==a[index])   //如果不能判断中间元素属于第一个递增元素还是第二个递增元素,则顺序查找
	  {
	    return minorder(a,index,index2);
	  }

	  if(a[mid]>=a[index])
		  index=mid;
	  if(a[mid]<=a[index2])
		  index2=mid;
	}
   return a[mid];
}

int minorder(int a[],int index,int index2)
{
   int result=a[index];
   int i;
   for(i=index+1;i<=index2;i++)
   {
     if(result>a[i])          //顺序查找比较,找到最小的元素
		 result=a[i];
   }
   return result;
}

int main()
{
  int a[5];
  int i,x;
  for(i=0;i<5;i++)
  {
	  scanf("%d",&a[i]);
  }

  x=min(a,5);
  printf("%d\n",x);

  return 0;
}</span>
时间: 2024-10-12 18:28:39

求旋转数组的最小数字算法的解析以及完整c语言代码实现的相关文章

【C语言】求旋转数组的最小数字,输入一个递增排序的数组的一个旋转,输出其最小元素

//求旋转数组的最小数字,输入一个递增排序的数组的一个旋转,输出其最小元素 #include <stdio.h> #include <string.h> int find_min(int arr[],int len) { int i = 0; for (i = 1; i < len; i++) { if (arr[i] < arr[0]) return arr[i]; } return arr[0]; } int main() { int i; int arr1[] =

程序员面试题目总结--数组(三)【旋转数组的最小数字、旋转数组中查找指定数、两个排序数组所有元素中间值、数组中重复次数最多的数、数组中出现次数超过一半的数】

转!http://blog.csdn.net/dabusideqiang/article/details/38271661 11.求旋转数组的最小数字 题目:输入一个排好序的数组的一个旋转,输出旋转数组的最小元素. 分析:数组的旋转:把一个数组最开始的若干个元素搬到数组的末尾.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1.这道题最直观的解法并不难.从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N).但这个思路没有利用输入数组

【剑指offer】旋转数组的最小数字

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 分析描述: 求一个数组中的最小值,最简单的办法就是逐个比较数组中各个元素的值,遍历完整个数组,即可得数组中最小元素.但这种方法存在的问题是时间复杂度为O(n). 利用题目中给出的条件:递增排序数组的旋转.利用递增排序的特点,可以用二分查找方法实现时间复杂度为O(logn)的查找.

剑指:旋转数组的最小数字

旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个升序的数组的一个旋转,输出旋转数组的最小元素. 例如数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的一个旋转,该数组的最小值为 1. 数组可能包含重复项. 注意:数组内所含元素非负,若数组大小为 0,请返回 -1. 样例 输入:nums=[2,2,2,0,1] 输出:0 解法 解法一 直接遍历数组找最小值,时间复杂度 O(n),不推荐. class Solution { /**

11&amp;12. 旋转数组的最小数字

面试题11. 旋转数组的最小数字(无重复元素) 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1. 示例 1: 输入:[3,4,5,1,2] 输出:1 示例 2: 输入:[2,2,2,0,1] 输出:0 class Solution { public int findMin(int[] nums) { int l = 0, h

剑指offer java -查找旋转数组的最小数字

/** * Created by wqc on 2017/7/18. * 查找旋转数组的最小数字 * 把一个数组最开始的若干个元素搬到数组的末尾,称为数组的旋转 * 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素 * 如:3,4,5,1,2 为1,2,3,4,5的一个旋转,最小值为1 */public class Problem8_findMinNumber { public Integer findMinNum(int[] array) { if(array == null) { r

《剑指offer》— JavaScript(6)旋转数组的最小数字

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

剑指Offer面试题:7.旋转数组的最小数字

一.题目:旋转数组的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 这道题最直观的解法并不难,从头到尾遍历数组一次,我们就能找出最小的元素.这种思路的时间复杂度显然是O(n).但是这个思路没有利用输入的旋转数组的特性,肯定达不到面试官的要求. 我们注意到旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的

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

题目1386:旋转数组的最小数字 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6708 解决:1505 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数. 输入的第二行包括n