算法5.旋转数组的最小数字


题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [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

解题思路

方法:二分法

时间复杂度:$O(log_2n)$ 若数组中所有元素都相同,则退化到$O(N)$

空间复杂度:$O(1)$

代码如下

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int start = 0;
        int end = numbers.size()-1;
        int mid;
        while (start < end)
        {
            mid = (start + end) / 2;
            if(numbers[mid] > numbers[end])
                start = mid+1;
            else if(numbers[mid] < numbers[end])
                end = mid;
            else 
                end--;
        }
        cout<<numbers[start]<<endl;
        return numbers[start];   
    }
};

解法分析

旋转后图示

如上图所示,由于旋转,数组呈两次递增状态,最低点夹在中间。通过二分法可以判定出最低点的位置。具体判定如下:

start=0end=size()-1

  • mid所处的值大于start所处的值时,证明最低点在右边,因此二分法取后者
  • mid所处的值小于start所处的值时,证明最低点在左边,因此二分法取前者
  • 当数组所有元素都是同一个值时,上述方法不再试用,二分法相当于遍历了一遍数组。

解法注意点

主要在于当mid所处的值等于start所处的值时,要怎么去处理二分法。上述代码是将end往前移动了一位。其形式相当于遍历。从代码量来说,不失为一种好方法。


文章作者: ray
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ray !
评论
 上一篇
算法6.矩阵中的路径找寻 算法6.矩阵中的路径找寻
题目描述请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×
2020-09-25
下一篇 
算法4.前序中序重建二叉树 算法4.前序中序重建二叉树
题目描述输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例 1: 给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,1
2020-09-20
  目录