• 剑指Offer——旋转数组的最小数字


    题目:

    这道题有三种思路:

    1. 以第一个元素为最小值min,直接遍历一遍,每个元素都与min进行比较,当当前元素比最小值min小则更新min的值,这里的时间复杂度是O(n)
    2. 利用数组的特性,我们可以知道只要a[i+1] < a[i]那么就可以确定a[i+1]就是最小值,这里的时间复杂度大概是O(1)~O(n)之间,取决于最小值在哪
    3. 还是利用数组的特性:我们可以肯定,最左边的元素一定比最右边的元素大,这时候只需要取数组正中间的元素来进行比较,就可以确定中间的元素处于较大元素组成的区域(我们这里称之为左区)还是较小元素组成的区域(右区),确定的方法很简单,如果中间的元素比左边的大,那么可以确定在左区,就需要往右边搜索,如果比左边的元素小,那么定然是在右区,就要往左边找。时间复杂度在O(1)~O(n/2)之间

    1、2很简单,所以这里就不放出代码了,我们只看3:

    class Solution {
    public:
        int minNumberInRotateArray(vector<int> rotateArray) {
            int size = rotateArray.size();
            if(size == 0) {
                return 0;
            }
            
            int left = rotateArray[0];
            int right = rotateArray[size - 1];
            
            int idx = size / 2;
            int res = 0;
            while(idx > 0 && idx < size) {
                if(rotateArray[idx] > left && rotateArray[idx] <= rotateArray[idx + 1]) {
                    // 左区
                    ++idx;
                }
                else if(rotateArray[idx] < right && rotateArray[idx] >= rotateArray[idx - 1]) {
                    // 右区
                    --idx;
                }
                else {
                    // 此时我们在边界,但是不确定idx此时在左区最右边还是右区最左边
                    res = rotateArray[idx] > rotateArray[idx + 1] ? rotateArray[idx + 1] : rotateArray[idx];
                    break;
                }
            }
            return res;
        }
    };
    
  • 相关阅读:
    【BZOJ3166】ALO(主席树)
    【UOJ#188】Sanrd(min_25筛)
    伯努利数
    【51Nod1258】序列求和V4(FFT)
    【BZOJ5306】[HAOI2018]染色(NTT)
    【BZOJ4943】【NOI2017】蚯蚓排队(哈希)
    【BZOJ4912】天才黑客(最短路,虚树)
    【BZOJ5333】荣誉称号(动态规划)
    NOI2018前的每日记录
    【BZOJ1088】扫雷(递推)
  • 原文地址:https://www.cnblogs.com/yejianying/p/jianzhioffer_minNumberInRotateArray.html
Copyright © 2020-2023  润新知