美文网首页
LeetCode 33. 搜索旋转排序数组

LeetCode 33. 搜索旋转排序数组

作者: 草莓桃子酪酪 | 来源:发表于2022-09-09 11:53 被阅读0次
    题目

    整数数组 nums 按升序排列,数组中的值互不相同。在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
    给你旋转后的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
    你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

    例:
    输入:nums = [4,5,6,7,0,1,2], target = 0
    输出:4

    方法:二分查找

    因为要求使用时间复杂度为 O(log n) 的算法,所以采用二分查找

    • left 和 right 分别表示左右指针,left 指向数组的首部,right 指向数组的尾部
    • 循环直至 left 位于 right 的右侧
      • mid 表示此时中点
      • 若 mid 下标对应的元素值等于目标值 target,那么找到目标值,返回此时下标
      • 因为此时的数组 nums 是通过一次旋转得到的,那么从中间分开后,两侧至少有一侧是升序排列的。若左边新数组的首部元素值 nums[0] 小于尾部元素值 nums[mid],及左边数组是升序排列的,那么可以通过判断目标值 target 是否位于该区间内,缩小查找范围
        • 若目标值 target 存在于 [[nums[0], nums[mid]),那么目标值在该区间内,缩小范围,将右指针 right 指向中点左移一步后的位置 mid - 1
        • 若目标值 target 不存在于 [nums[0], nums[mid]),那么目标值在右边新数组中,缩小范围,将左指针 left 指向中点右移一步后的位置 mid + 1
      • 否则,右边数组是升序排列的,那么可以通过判断目标值 target 是否位于该区间内,缩小查找范围
        • 若目标值 target 存在于 (nums[mid], nums[len(nums)-1]],那么目标值在该区间内,缩小范围,将左指针 left 指向中点右移一步后的位置 mid + 1
        • 若目标值 target 不存在于 (nums[mid], nums[len(nums)-1]],那么目标值在左边新数组中,缩小范围,将右指针 right 指向中点左移一步后的位置 mid - 1
    • 若不存在目标值 target,返回 -1
    class Solution(object):
        def search(self, nums, target):
            left, right = 0, len(nums)-1
            while left <= right:
                mid = (left + right) // 2
                if nums[mid] == target:
                    return mid
                if nums[0] <= nums[mid]:
                    if nums[0] <= target < nums[mid]:
                        right = mid - 1
                    else:
                        left = mid + 1
                else:
                    if nums[mid] < target <= nums[len(nums)-1]:
                        left = mid + 1
                    else:
                        right = mid - 1
            return -1
    
    相关知识
    • 二分查找:
      首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
      要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
    参考

    代码相关:https://leetcode.cn/problems/search-in-rotated-sorted-array/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/
    二分查找:https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/10628618?fr=aladdin

    相关文章

      网友评论

          本文标题:LeetCode 33. 搜索旋转排序数组

          本文链接:https://www.haomeiwen.com/subject/uyfinrtx.html