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

本文介绍了一种高效查找旋转数组最小元素的方法,通过二分查找法将时间复杂度降低至O(logn),并提供了详细的解题思路及C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试题–【剑指Offer】 题目解答

题目要求

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

解题思路

实际上这道题并不难,只需要遍历整个数组就可以知道最小的数字是什么。但是,该方法的时间复杂度O(n)没有很好的利用到旋转数组的特性,所以可能不会达到面试官的要求。

我们观察一下旋转之后的数组:{3,4,5,1,2}实际上是两个递增的子序列{3,4,5}和{1,2}并且前面子序列的元素都大于或者等于后面子序列的元素。关键:最小的元素刚好是两个子序列的分界点。排序的数组中,我们通常使用二分查找法实现O(logn)的查找。所以我们给出如下的步骤:

(1)设置两个指针,分别指向第一个子序列的第一个元素和第二个子序列的最后一个元素。
(2)接着我们找到,数组的中间元素(如上述中的5),这里有两种情况,一种是在第一个子序列的最后一位,另一种是第二个子序列的第一位。我们可以根据情况来调整指针1或者指针2。以此来减少寻找的范围。
(3)无论是(2)中那种的移动方法,都会缩小寻找的范围,最终指针1会指向第一个子序列的最后一个元素,指针2会指向第二个子序列的第一个元素。(就是指针1和指针2相邻),而最小的元素就是指针2指向的元素。到这里程序就算结束了。

这里边有个问题:
当旋转数组和原数组一样的时候,即旋转了原数组的前0个元素,那么此时无法计算中间元素,就会报错,所以我们在程序里初始化中间元素的值为数组首元素来避免这个问题。

这里边的重点:
找到中间元素是位于第一个子序列还是第二个子序列?
终止循环的条件是什么:当指针1和指针2相邻,数组索引差1的时候。

主要代码 c++

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
          if(rotateArray.size()==0) return 0; //若数组大小为0,返回0
          int index1 = 0;
          int index2 = rotateArray.size() - 1;
          int mid = index1; // 防止旋转数组和原数组一致(只旋转0个元素)
          while(rotateArray[index1] >= rotateArray[index2])
          {
              if(index2-index1==1) // 停止条件
              {
                  mid = index2; // 最小元素是第二个子序列的首元素
                  break;
              }
              mid = (index1 + index2) / 2; // 寻找中间元素
              if(rotateArray[index1]<=rotateArray[mid]) //一定要有等号
                  index1 = mid;
              else if(rotateArray[index2]>=rotateArray[mid])
                  index2 = mid;
          }
        return rotateArray[mid];
    }
};

总结

实际上二分查找的思想就是根据不断调整指针1和指针2的值来减小搜索的范围,直到两个指针相遇,停止循环。

相关习题:
解答:leetcode 35 Search Insert Position.(搜索元素插入数组的位置)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值