1. 程式人生 > >隨筆-尋找旋轉排序陣列中的最小值(有重複元素)

隨筆-尋找旋轉排序陣列中的最小值(有重複元素)

題目:

假設按照升序排序的陣列在預先未知的某個點上進行了旋轉。

( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。

請找出其中最小的元素。

注意陣列中可能存在重複的元素。

示例 1:

輸入: [1,3,5]
輸出: 1
示例 2:

輸入: [2,2,2,0,1]
輸出: 0
說明:

這道題是 尋找旋轉排序陣列中的最小值 的延伸題目。
允許重複會影響演算法的時間複雜度嗎?會如何影響,為什麼?

思路:這篇部落格只介紹什麼情況會遇見重複,第一種重複是迴圈剛開始的時候,如 1 2 1 1 這種,那麼我們需要看陣列後面的重複元素當他不重複時,前一項大於後一項,那麼就找到了最小的元素,直接返回就好。 第二次遇見重複因為是排序陣列那麼肯定是最小的元素。

如果不懂怎麼尋找最小陣列 ,請參照此篇部落格 尋找旋轉排序陣列中的最小值(無重複元素)

class Solution {
    public int findMin(int[] nums) {
        if(nums==null){
            return -1;
        }else if(nums.length==1 || nums[0]<nums[nums.length-1]){
            return nums[0];
        }
        int l=0;
        int r=nums.length-1;
        boolean b=false;
        while(l<r){
            if(nums[l]==nums[r]&&b==false){ //判斷迴圈開始時的重複
                if(l<r&& nums[r-1]==nums[r]){
                    r--;
                }else if(nums[r-1]>nums[r]){
                    return nums[r];
                }else{
                    r--; //迴圈開始時重複,num[r]並不是最小的元素,為了使頭尾不一樣 r--或者l++都可以;
                    b=true;
                }
                continue;
            }
            if(nums[l]==nums[r]){  //第二次l  r  會重複則遇見最小元素
                return nums[l];
            }
            int mid=(l+r)/2;
            if(nums[mid]>nums[r]){ //如果在前半段
                l=mid+1;
            }else{
                r=mid;
            }
        }
        return nums[l];
    }
}