查找旋转数组的最小数字

来源:互联网 发布:php音乐网站设计 编辑:程序博客网 时间:2024/06/02 02:10

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

关于思路
1.寻找一个数组中的最小的数字,可以直接遍历整个数组。

2.我们应该抓住两点,首先这个数组本来是递增的,那么我完成一次旋转以后,数组的内部可以看成是两个递增的数        组,那么最小的数字一定在最大的数字后面。可以设定边界值,利用二分查找来找到最小的元素。

3.对于一些递增不明显的是否可以处理,比如说{1,0,1,1,1}是数组{0,1,1,1,1}的旋转,此时在处理的时候,边界值和中间   值都一样,二分查找就不行了,就只能顺序遍历。


关于代码

依据上诉三条思路写出如下三个代码:

代码一:

int Findmin(int *a,int length)
 {
  if (a == NULL)
  return 0;
  int  i = 0;
  while (i<length)
  {
  if (a[i] < a[i + 1])
  {
  i++;
  }
  else
  {
  return a[i+1];
  }
 
  }
 }

结果为:


代码二:

 int Findmin(int*a, int length)
 {
  if (a == NULL || length <= 0)
  printf("ERROR");
  int index1 = 0;
     int index2 = length - 1;
  int middle = 0;
  while (a[index1] >= a[index2])
  {
  if (index2 - index1 == 1)
  {
  middle = index2;
  break;
  }
  middle = (index1 + index2) >> 1;
  if (a[index1] <= a[middle])
  {
  index1 = middle;
  }
  else if (a[index2] >= a[middle])
  index2 = middle;
  }
  return  a[middle];
 }

结果:


代码三:

int min(int *a,int index1,int index2)
{
int i = 0;
int ret = a[index1];
for (i=index1+1; i < index2; i++)
{
if (ret >a[i])
{
ret = a[i];
}
}
return ret;
}
int Findmin(int*a, int length)
{
if (a == NULL || length <= 0)
printf("ERROR");
int index1 = 0;
int index2 = length - 1;
int middle = 0;
while (a[index1] >= a[index2])
{
if (index2 - index1 == 1)
{
middle = index2;
break;
}
middle = (index1 + index2) >> 1;
if (a[index1] == a[middle] && a[middle] == a[index2])
{
return min(a,index1,index2);
}
if (a[index1] <= a[middle])
{
index1 = middle;
}
else if (a[index2] >= a[middle])
index2 = middle;
}
return  a[middle];
}

结果:



关于总结:

代码一的代码只能解决一般问题不能解决之前提到的特殊问题,而且代码一的办法时间复杂度是O(N),代码二的代码也只能解决一般情况不能解决特殊情况,但是用了二分查找的思想,降低了时间复杂度,代码三的代码不仅能解决一般情况还能解决特殊情况,所以本人觉得代码三的代码可用性更高。

原创粉丝点击