有序旋转数组最小值

在有序旋转数组中找到最小值

升序旋转数组最小值

【题目】
有序数组arr可能经过一次旋转处理,也可能没有,且arr可能存在重复的数。
例如,有序数组[1,2,3,4,5,6,7],可以旋转处理成[4,5,6,7,1,2,3] 等。
给定一个可能旋转过有序数组arr,返回arr中的最小值

算法思路

根据题目分析
有序指升序;
旋转处理将升序数组分成前后两部分,进行整体位置交换;
可能旋转,可能不旋转,返回其中最小值

直接遍历获取最小值,时间复杂度为 O ( N ) O(N) O(N)

现在考虑升序数组和旋转操作的性质,给定的数组arr最多下降一次值(散点构成的两条向上的直线)。
使用二分查找的思想,平均时间复杂度为 O ( l o g N ) O(logN) O(logN),最坏时间复杂度为 O ( N ) O(N) O(N)

思维扩展
同理可以在升序旋转数组中找到最大值;
也可以先找到最小值的索引,最小值前一位就是最大值。(若最小值索引为0,则最大值索引为-1——len(arr) - 1)。


相应代码

# 有序旋转数组最小值
def rotate_arr_minimum(arr):
    if arr is None or len(arr) == 0:
        return None
    low = 0
    high = len(arr) - 1
    while low <= high:
        # 包含不超过两个值
        if high - low <= 1:
            minimum = arr[low]
            if arr[high] < arr[low]:
                minimum = arr[high]
            return minimum
        # 无旋转
        if arr[low] < arr[high]:
            return arr[low]
        # 二分查找
        mid = (low + high) // 2
        if arr[low] > arr[mid]:
            high = mid
        elif arr[mid] > arr[high]:
            low = mid
        else:
            # arr[low] == arr[mid] == arr[high], 最小值在下面五个位置中
            cand_indexes = [low + 1, mid - 1, mid, mid + 1, high -1]
            minimum = arr[cand_indexes[0]]
            for index in cand_indexes:
                if arr[index] < minimum:
                    minimum = arr[index]
            return minimum

# 简单测试
if __name__ == '__main__':
    arr = [4, 5, 6, 7, 1, 2, 3]
    print(rotate_arr_minimum(arr))  # 1

    arr = [1, 1, 1, 1, 1, 1, 1]
    print(rotate_arr_minimum(arr))  # 1

    arr = [1, 0, 1, 1, 1, 1, 1]
    print(rotate_arr_minimum(arr))  # 0

    arr = [1, 1, 1, 1, 1, 0, 1]
    print(rotate_arr_minimum(arr))  # 0

有任何疑问和建议,欢迎在评论区留言和指正!

感谢您所花费的时间与精力!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值