面试题8:旋转数组的最小数字(剑指offer)

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

题目分析:

我们可以通过旋转以后的数组中的元素的分布方式找出其中的一些规律:

数组{3,4,5,1,2}中,最左边的数字(3)大于最右边的数字(2),由于原数组是递增排序的,所以左边的数字(3,4,5)都比右边的数字(1,2)大,这样我们可以将该数组划分为两个序列分别是序列1{3,4,5}、序列2{1,2},那么我们就可以按照二分查找的方法查找最小数字1。

具体查找方法如下:

如:该数组为

int arr[5]={3,4,5,1,2};

第一步:用两个指针分别指向该数组的第一个元素和最后一个元素,即arr[0]arr[4];

第二步:查找数组的中间元素arr[mid];

第三步:用中间元素和数组的第一个元素分别和第一个元素和最后一个元素作比较,如果中间元素比第一个元素大,那么该中间元素一定是在第一个序列中的,这时,将第一个指针指向中间元素即arr[2];如果中间元素小与最后一个元素,那么中间元素一定是在第二个序列中的,这时将第二个指针指向中间元素。

第四步:重复上述步骤二,直到第一个指针指向第一个序列的最后一个元素,第二个指针指向第二个序列的第一个元素,即两个指针相邻,那么最小的元素就是第二个指针所指向的元素。

如图:

通过分析题目我们就可以很好的写出程序了,当然我们也要考虑到其他情况,当数组中元素为

{1,1,1,0,1}或{1,0,1,1,1}时,我们无法判断中间元素在第几个序列中,这是我们就要用另一种方法进行查找最小元素了。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int Min(int *arr,int size)
{
     assert(arr);
     assert(size >=0);
     int left = 0;
     int right = size - 1;
     int mid = left;
     while (arr[left] >= arr[right])
     {
          if (right - left == 1)//若两指针相邻,则后一个指针所指的元素为最小值
      {
           mid = right;
           break;
      }
      mid = (left + right) / 2;//求中间元素
      if ((arr[left] == arr[right]) && (arr[mid] == arr[left]))
 //若出现中间元素和左右两边的元素都相等时直接找最小元素,用下面的函数实现
           return MinInOrder(arr,left,right);
      if (arr[mid] >= arr[left])
      {
           left = mid;
      }
      else if (arr[mid] <= arr[right])
      {
           right = mid;
      }
    }
         return arr[mid];
}
 int MinInOrder(int *arr, int left, int right)
{
     int i = 0;
     int min = arr[left];
     for (i = left + 1; i < right; i++)//直接遍历数组寻找最小的元素
     {
           if (arr[left]>arr[i])
          {
               min = arr[i];
               break;
          }
     }
     return min;
}
时间: 2025-01-16 13:59:33

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

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

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

旋转数组的最小数字-剑指Offer

旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 思路 使用二分查找,因为该旋转数组是两段排序好的数组,可根据中间值判断中间值属于哪个排列数组,逐渐缩小范围. 注意考虑特殊情况,数组可能出现多个元素相等 代码 public class Sol

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

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if (rotateArray.size() == 0

旋转数组的最小数字——剑指offer

题目:把一个数组最开始的若干各元素搬到数组的末尾,称之为旋转数组,输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}是数组{1,2,3,4,5}的一个旋转,该数组的最小值为1: 1 #include<stdio.h> 2 int MinInOrder(int r[], int p1, int p2) 3 { 4 int result = r[p1]; 5 for (int i = p1 + 1; i <= p2; i++) 6 { 7 if (r[i

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

http://ac.jobdu.com/problem.php?pid=1386 WA了一发,因为没有考虑本身有序的情况. 貌似是cuhk曾经的面试题,当初准备CUHK面试的时候在别人博客看到过. 思路二分,朴素的想法我有,但是特殊情况没考虑好. *mid与*first比,*mid与*end比,*mid>=*first,说明*mid现在在前面的有序部分. *mid<*first,说明*mid在后面的有序部分. 对应修改first和end就行了 特殊情况有两个: 1.本身有序 2.1 1 1 0

【剑指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面试题8——旋转数组的最小数字

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

面试题:旋转数组的最小数字

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素.例如输入{1,2,3,4,5}的一个旋转为{3,4,5,1,2},该数组的最小值为1. 分析:首先想到的肯定是遍历一遍找出最小的元素,但是这样的时间复杂度为o(n),且没有利用到旋转数组的特性.观察可得,旋转数组可以分为两个有序的子数组.而且前一个数组的元素均大于后一个数组.这个发现对于我们解题将起到一个至关重要的作用.而更神奇的是最小的元素刚好是这两个子数组的分界

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

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

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

题目:把一个数组最开始的若干个元素搬到数据的末尾,我们称之为 数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组 的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该 数组的最小值为1. 这道题可以使用类似于二分查找的思想,算法思路如下: 1.假设有一个旋转数组A,我们设两个索引p1,p2 2.p1指向为数组第一个元素,p2指向为数组最后一个元素 3.取p3为数组中的中间元素 4.比较p3指向的元素与p1,p2.若p3>p1,则说明前半个    子数组为递增数