[LeetCode]110. Find Minimum in Rotated Sorted Array旋转数组最小值

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.

You may assume no duplicate exists in the array.

 

解法1:顺序查找,时间复杂度O(n)。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int minVal = INT_MAX;
        for(int i = 0; i < nums.size(); ++i) {
            minVal = min(minVal, nums[i]);
        }
        return minVal;
    }
};

 

解法2:因为数组是从有序数组旋转得到的,而有序数组的查找可以使用二分查找,因此本题也可以尝试使用二分查找。因为数组是由升序数组旋转得到,并且无重复值,因此:(1)如果数组首元素小于数组尾元素,则数组实际未旋转,返回首元素即可;(2)如果不是情况(1)则必有数组首元素大于数组尾元素。此时找到数组的中间元素,再分几种情况:(2.1)数组首元素小于数组中间元素,此时说明前半部分数组是有序的,且最小元素必在后半部分;(2.2)数组首元素大于数组中间元素,此时数组后半部分有序,且最小元素在前半部分。对这两种情况都可以递归调用二分查找解决。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int n = nums.size();
        if (n <= 1) return n == 1 ? nums[0] : 0;
        return binaryFind(nums, 0, n - 1);
    }
private:
    int binaryFind(vector<int>& nums, int left, int right) {
        if (nums[left] < nums[right]) return nums[left];
        if (left == right) return nums[left + 1];
        int mid = (left + right) >> 1;
        if (nums[left] < nums[mid]) left = mid;
        else right = mid;
        return binaryFind(nums, left, right);
    }
};

left总是指向前面递增数组的元素,而right总是指向后面递增数组的元素。最终left将指向前面递增数组的最后一个元素,而right则指向后面递增数组的第一个元素,因此最终left+1=right,返回结果。如果存在旋转,则最终right所指就是整个数组的最小元素。循环形式代码:

class Solution {
public:
    int findMin(vector<int>& nums) {
        int n = nums.size(), left = 0, right = n - 1, mid = 0;
        if (n <= 1) return n == 1 ? nums[0] : 0;
        while (nums[left] >= nums[right]) {
            if (right == left + 1) return nums[right];
            mid = (left + right) >> 1;
            if (nums[left] < nums[mid]) left = mid;
            else right = mid;
        }
        return nums[mid];
    }
};

 

posted @ 2015-12-15 09:33  AprilCheny  阅读(1022)  评论(0编辑  收藏  举报