JZ: 11 旋轉數組的最小數字

題目:

把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。
例如,數組 [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(n),空間O(1)
因爲題目中所提供的是一個排序的原始數組,因此我們只要循環一次,找到變小的那個元素,這個元素就是最小元素;如果如果沒有,那麼第一個元素就是我們要找的元素了;
從給這個方案中的思考中,我們知道代碼中要對 未經旋轉的數組進行處理,不妨設置一個測試用例爲
[1,2,3,4,5];

方案二:快排思想/ 二分思想 / 切分數組:時間複雜度:O(logn), 空間O(1)
對於[3,4,5,1,2], 他是兩段連續增長的數組拼接而成的
我們取 起始點、中點、 終止點三個點進行比較,3 > 5 && 5 > 2
可見第一段是遞增的,而第二段顯然並非遞增,因此最小值在第二段中;

我們重複這個過程,5 > 1 && 1 < 2,第一段不是遞增的,因此對第一段繼續;
而此時這兩個元素只相差1個下標因此這段中的第二個值就是我們要的最小值

據此不難實現如下代碼:

while(last - first >= 1){
  if(last - first == 1)
         return numbers[last];

     int mid_index = (first + last)/2;
     // 註釋一:
// if(numbers[first] == numbers[last] && numbers[first] == numbers[mid_index]){
            //     return find_byOrder(numbers);
            // }

     if(numbers[first] > numbers[mid_index]){
         last = mid_index;
     }

     else if(numbers[last] < numbers[mid_index]){
         first = mid_index;
     }
 }
 return numbers[0];	// 註釋2

對於剛剛說的測試用例 [1,2,3,4,5],這並不能滿足,對於原地旋轉的情況我們沒有判斷,其實只需要在return的時候:註釋二;

對於小於等於3個元素的數組呢?while中的判斷條件也有問題:旋轉過後的數組的特點就是 first的數值要大於last,因此修改爲:numbers[first] >= numbers[last]

還有一點細節!如果最初的 first 、last、mid_index對應的數值都相等怎麼辦?
這將不會進行任何操作,一直循環

比如:【1,0,1,1,1,1】
這時可能有一些其他的辦法,這裏我直接調用方法一函數,遍歷查找;

方法二:代碼:

class Solution {
public:
    int find_byOrder(vector<int>& numbers){
        int index = 0;
        for(int i = 1;  i< numbers.size(); i++)
        {
            if(numbers[i] < numbers[i - 1]) {
                index = i;
            }
        }
        return numbers[index];
    }
    
    int minArray(vector<int>& numbers) {

        if(numbers.size() == 0)
            return -9999;

        int first = 0, last = numbers.size()-1;

        while(numbers[first] >= numbers[last]){
            if(last - first == 1)
                return numbers[last];

            

            int mid_index = (first + last)/2;

            if(numbers[first] == numbers[last] && numbers[first] == numbers[mid_index]){
                return find_byOrder(numbers);
            }

            if(numbers[first] > numbers[mid_index]){
                last = mid_index;
            }

            else if(numbers[last] < numbers[mid_index]){
                first = mid_index;
            }
        }
        return numbers[0];
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章