劍指offer 10- 旋轉(zhuǎn)數(shù)組的最小數(shù)字

把一個(gè)數(shù)組最開始的若干個(gè)元素搬到數(shù)組的末尾,我們稱之為數(shù)組的旋轉(zhuǎn)。

輸入一個(gè)升序的數(shù)組的一個(gè)旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素。

例如數(shù)組 {3,4,5,1,2}為 {1,2,3,4,5} 的一個(gè)旋轉(zhuǎn),該數(shù)組的最小值為 1

數(shù)組可能包含重復(fù)項(xiàng)。

注意:數(shù)組內(nèi)所含元素非負(fù),若數(shù)組大小為 0,請(qǐng)返回 ?1

樣例

輸入:nums = [2, 2, 2, 0, 1]

輸出:0

分析:

  • 理解二分法的本質(zhì):
    尋找某種性質(zhì)的分界點(diǎn),只要可以找到某種性質(zhì),使得區(qū)間的前半部分滿足,后半部分不滿足,那么就可以用二分法把這個(gè)分界點(diǎn)找到。

對(duì)于本題:



發(fā)現(xiàn)除了最后水平的一段之外,其余部分滿足二分性質(zhì):豎直線左邊的數(shù)滿足 nums[i]≥nums[0] 而豎直線右邊的數(shù)不滿足這個(gè)條件。
分界點(diǎn)就是整個(gè)數(shù)組的最小值。
所以我們先將最后水平的一段刪除即可。

另外,要考慮到數(shù)組完全單調(diào)的特殊情況:
當(dāng)我們刪除最后水平的一段之后,如果剩下的最后一個(gè)數(shù)大于等于第一個(gè)數(shù),則說明數(shù)組完全單調(diào)。

時(shí)間復(fù)雜度分析
二分的時(shí)間復(fù)雜度是 O(logn),刪除最后水平一段的時(shí)間復(fù)雜度最壞是 O(n),所以總時(shí)間復(fù)雜度是 O(n)。

class Solution {
public:
    //二分的時(shí)間復(fù)雜度是 O(logn),
    //刪除最后水平一段的時(shí)間復(fù)雜度最壞是 O(n),所以總時(shí)間復(fù)雜度是 O(n)。
    int findMin(vector<int>& nums) {
        // return nums.empty() ? -1 : *min_element(nums.begin(),nums.end());
        int n = nums.size() - 1;
        //若數(shù)組大小為 0,請(qǐng)返回 ?1
        if(n<0) return -1;
        //把最后水平的一段重復(fù)元素去掉,便于后面的二分。
        //把n=0的情況去掉(n=0時(shí),數(shù)組長(zhǎng)度為1,直接輸出nums[0]即可)
        while (n>0 && nums[n] == nums[0]) n--;
        //去掉最后水平的一段后,如最后一個(gè)數(shù)大于等于第一個(gè)數(shù),則數(shù)組完全單調(diào)。
        if(nums[n]>=nums[0]) return nums[0];
        
        int l=0,r=n;
        while(l<r) {
            int mid = l+r >> 1; //[l,mid] [mid+1,r]
            if(nums[mid]<nums[0]) r=mid;
            else l =mid+1;
        }
        return nums[l];
    }
};

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容