***153. 寻找旋转排序数组中的最小值

1. 题目描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

请找出其中最小的元素。

你可以假设数组中不存在重复元素。

示例 1:

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

输入: [4,5,6,7,0,1,2]
输出: 0

 

2.  思路

1)找到数组的中间元素 mid。

2) 如果中间元素 > 数组第一个元素,我们需要在 mid 右边搜索变化点。

3) 如果中间元素 < 数组第一个元素,我们需要在 mid 做边搜索变化点。

 

 

上面的例子中,中间元素 6 比第一个元素 4 大,因此在中间点右侧继续搜索。

4) 当我们找到变化点时停止搜索,当以下条件满足任意一个即可:
    nums[mid] > nums[mid + 1],因此 mid+1 是最小值。

    nums[mid - 1] > nums[mid],因此 mid 是最小值。

 

3. 解法

class Solution:
    def findMin(self, nums: List[int]) -> int:
        if len(nums)==1:
            return nums[0]
        if nums[0]<nums[-1]:
            return nums[0]
        left, right = 0, len(nums)-1
        while(left<=right):
            mid = left+(right-left)//2
            if nums[mid]>nums[mid+1]:
                return nums[mid+1]
            if nums[mid-1]>nums[mid]:
                return nums[mid]
            if nums[mid]>nums[0]:
                left=mid+1
            else:
                right=mid-1

 

 

另解:

class Solution:
    def findMin(self, nums: [int]) -> int:
        left, right = 0, len(nums) - 1
        while left < right:
            mid = (left + right) // 2
            if nums[mid] > nums[right]: left = mid + 1
            else: right = mid
        return nums[left]

 

有重复数字的解法

154. 寻找旋转排序数组中的最小值 II

class Solution:
    def findMin(self, nums: List[int]) -> int:
        left, right = 0, len(nums) - 1
        while left < right:
            mid = (left + right) // 2
            if nums[mid] > nums[right]: left = mid + 1
            elif nums[mid] < nums[right]: right = mid
            else: right = right - 1 # key
        return nums[left]

 

 

二分法再利用:

162. 寻找峰值

public class Solution {
    public int findPeakElement(int[] nums) {
        int l = 0, r = nums.length - 1;
        while (l < r) {
            int mid = (l + r) / 2;
            if (nums[mid] > nums[mid + 1])
                r = mid;
            else
                l = mid + 1;
        }
        return l;
    }
}

或者复杂度高一点的线性搜索:

class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        for i in range(len(nums)-1):
            if nums[i]>nums[i+1]:
                return i
        return len(nums)-1

 

posted @ 2019-08-18 10:32  三年一梦  阅读(177)  评论(0)    收藏  举报