旋转排序数组的最小数

时间:2022-07-22
本文章向大家介绍旋转排序数组的最小数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

问题描述:

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [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

解决方案

通过旋转后数组变为两段相连的递增的序列,该问题说白了就是找第二段的开头位置,也就是找第一个乱序位置,使用二分搜索解决。

左边元素,右边元素,中间元素分别记做nums[left], nums[right], nums[mid]

当nums[left] < nums[right]时表明从left到right已经是排好序的了,因此返回nums[left]即可

在nums[left] >= nums[right]情况下:

当nums[mid] > nums[right]时证明第一个乱序位置一定在mid + 1到right之间,因此left = mid + 1

当nums[mid] < nums[left]时表面第一个乱序位置一定在left到mid之间,因此right = mid

否则即nums[mid] <= nums[right],nums[mid] >= nums[left] 又是在nums[left] >= nums[right]情况下的,因此nums[mid] = nums[right] = nums[left],对于三个值都相等的情况,就不能再使用二分了,只能right–。

func minArray(numbers []int) int {
    if len(numbers) == 0{
        return 0
    }
    left := 0
    right := len(numbers) - 1
    for left < right{
        if numbers[left] < numbers[right]{
            break;
        }
        mid := (left + right) / 2
        if(numbers[mid] > numbers[right]){
            left = mid + 1
        }else if(numbers[mid] < numbers[left]){
            right = mid
        }else{
            right--
        }
    }
    return numbers[left];
}