Find Minimum in Rotated Sorted Array II(寻找旋转排序数组中的最小值 II )

问题

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

Notice

The array may contain duplicates.

Example
Given [4,4,5,6,7,0,1,2] return 0.

分析

因为数组是排过序的,所以只要找到第一个比它边小的元素就是答案,如果找不到就代表数组本身是全正序的,返回第一个元素即可。

代码

public class Solution {
    /**
     * @param num: a rotated sorted array
     * @return: the minimum number in the array
     */
    public int findMin(int[] num) {
        if (num == null || num.length == 0) {
            return -1;
        }
        for(int i=1;i

答案分析

九章算法

// version 1: just for loop is enough
public class Solution {
    public int findMin(int[] num) {
        //  这道题目在面试中不会让写完整的程序
        //  只需要知道最坏情况下 [1,1,1....,1] 里有一个0
        //  这种情况使得时间复杂度必须是 O(n)
        //  因此写一个for循环就好了。
        //  如果你觉得,不是每个情况都是最坏情况,你想用二分法解决不是最坏情况的情况,那你就写一个二分吧。
        //  反正面试考的不是你在这个题上会不会用二分法。这个题的考点是你想不想得到最坏情况。
        int min = num[0];
        for (int i = 1; i < num.length; i++) {
            if (num[i] < min)
                min = num[i];
        }
        return min;
    }
}

// version 2: use *fake* binary-search
public class Solution {
    /**
     * @param num: a rotated sorted array
     * @return: the minimum number in the array
     */
    public int findMin(int[] nums) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        
        int start = 0, end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == nums[end]) {
                // if mid equals to end, that means it's fine to remove end
                // the smallest element won't be removed
                end--;
            } else if (nums[mid] < nums[end]) {
                end = mid;
                // of course you can merge == & <
            } else {
                start = mid;
                // or start = mid + 1
            }
        }
        
        if (nums[start] <= nums[end]) {
            return nums[start];
        }
        return nums[end];
    }
}

九章的version1和我的方法是类似的。我的在找到时会立刻返回,不会把循环走完。在一些情况下会比它快一些。
九章version2的时间更短。

九章的version分析

mid等于end时,最小的可能在左边,右边全是end的值,也可能是在右边,左边全是end的值,所以只能end--;
mid大于end时,列表是循环了,最小的应该在右边(不包含mid);
mid小于end时,列表右边必然是正序,所以最小的在左边(包含mid)。

我的version2

public class Solution {
    /**
     * @param num: a rotated sorted array
     * @return: the minimum number in the array
     */
    public int findMin(int[] num) {
        if (num == null || num.length == 0) {
            return -1;
        }
        int l=0;
        int r=num.length-1;
        while(lnum[r]){
               l=mid+1;                    
            }else{
                r=mid;
            }
        }
        return num[l];
    }
}

分析使用左边

能否使用l作为参照?
mid等于l分析相同,略;
mid大于l时,左边必然正序,最小值可能是mid,也可能在右边;
mid小于l时,左边必须循环了,最小值在左边。
所以应该使用右边作为参照。

你可能感兴趣的:(Find Minimum in Rotated Sorted Array II(寻找旋转排序数组中的最小值 II ))