【劍指offer】11--旋轉數組的最小數字(二分查找)

原創博文,轉載請註明出處!ios

# 本文是牛客網《劍指offer》刷題筆記數組

1.題目

     旋轉數組的最小數字:輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。 例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。測試

     注意:給出的全部元素都大於0,若數組大小爲0,請返回0。spa

2.思路

image

  • 空數組查找最小元素:      

        輸出0指針

  • 非空數組查找最小元素:

# 若是輸入旋轉0個元素的旋轉數組,則第一個元素即最小元素     code

# 若是輸入旋轉n個元素的旋轉數組,則按二分查找和順序查找的思路查找最小元素blog

二分查找過程:排序

        旋轉數組特性:旋轉數組將原有序數組分紅遞增子數組1和遞增子數組2,遞增子數組1的元素>=遞增子數組2,最小元素是兩個子數組的分界線。設置輔助變量:指針left指向旋轉數組的第一個元素;指針mid指向旋轉數組中間位置的元素;指針right指向旋轉數組最後一個元素。get

      若是mid指向的元素>=left指向的元素,則mid位於遞增子數組1,數組中最小元素位與中間元素的後面,將left指向mid後,縮小一半的尋找範圍it

      若是mid指向的元素<=right指向的元素,則mid位於遞增子數組2,數組中最小元素位與中間元素的前面,將right指向mid後,縮小一半的尋找範圍

      若是mid指向的元素==left指向的元素==right指向的元素,則沒法肯定mid位於哪一個遞增子數組,沒法折半查找,只能順序查找

二分查找結束標誌:

      left指針始終指向遞增子數組1,right指針始終指向遞增子數組2,最終left指針指向遞增子數組1的最後一個元素,right指針指向遞增子數組2的第一個元素。當left+1=right時結束循環,right位置的元素即爲最小元素。7  

3.code

#include <iostream>
#include <vector>
using namespace std;

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray)
    {
        // 空數組
        int size = rotateArray.size();							//數組長度
        if(size == 0)
        {
            return 0;
        }

        // 非空數組
        int left = 0;											//左指針
        int right = size - 1;									//右指針
        int mid = 0;											//中間指針(未旋轉時直接輸出rotateArray[0])

        while(rotateArray[left] >= rotateArray[right])
        {
            // 循環結束標誌(左右指針相鄰)
            if(left+1 == right)
            {
                mid = right;
                break;
            }

            // 計算中間指針位置
            mid = left + (right - left) / 2;

            //特殊狀況:若是沒法肯定中間元素是屬於前面仍是後面的遞增子數組,只能順序查找
            if(rotateArray[left] == rotateArray[right] && rotateArray[mid] == rotateArray[left]){
                return MinInOrder(rotateArray, left, right);
            }
            //中間元素位於前面的遞增子數組,此時最小元素位於中間元素的後面
            if(rotateArray[mid] >= rotateArray[left]){
                left = mid;
            }
            //中間元素位於後面的遞增子數組,此時最小元素位於中間元素的前面
            else{
                right = mid;
            }
        }
        return rotateArray[mid];
    }
private:
    //順序尋找最小值
    int MinInOrder(vector<int> &num, int left, int right){
        int result = num[left];
        for(int i = left + 1; i <= right; i++){
            if(num[i] < result){
                result = num[i];
            }
        }
        return result;
    }
};
int main()
{
    Solution solution;
    vector<int> rotateArray = {4,5,1,2,3,4};
    cout<<solution.minNumberInRotateArray(rotateArray)<<endl;
    return 0;
}

4.複雜度

       時間複雜度O(logn)

5.測試用例

  • 空指針
  • 一個元素的數組
  • 未旋轉的數組
  • 旋轉的數組(無重複數字和有重複數字)
相關文章
相關標籤/搜索