LeetCode 33. Search in Rotated Sorted Array - 二分查找(Binary Search)系列题2

本文解析了一道关于在已旋转的有序整数数组中查找目标值的算法问题,介绍了如何利用二分查找思想,结合数组的旋转特性,实现O(logn)的时间复杂度解决方案。通过实例和代码展示了如何在不同情况判断目标值的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

There is an integer array nums sorted in ascending order (with distinct values).

Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].

Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

You must write an algorithm with O(log n) runtime complexity.

Example 1:

Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

Example 2:

Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1

Example 3:

Input: nums = [1], target = 0
Output: -1

Constraints:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • All values of nums are unique.
  • nums is an ascending array that is possibly rotated.
  • -104 <= target <= 104

这题是经典二分查找算法也就是LeetCode 704. Binary Search的变形,它把一个排好序的数组做了旋转从而破坏了数组的单调递增性,从而使得判断目标数是落在哪个区间的难度加大。

由于题目中是把一个排好序的数组做了旋转,也就是说旋转后的数组只有一个地方的递增性被破坏,要么是前半区间要么就是后半区间。而对于仍然是单调递增的那一半区间,我们很容易判断目标数是否在该区间,如不在那就肯定在另一半区间。因此本题的二分查找就分成以下两种情况分别进行判断:

1)前半区是单调递增的(nums[mid] >= nums[left]),如果target大于等于nums[left]且小于nums[mid],那么target肯定在前半区间,否则就是在后半区间。

2)后半区间是单调递增的(nums[mid] < nums[left]),如果target大于nums[mid]且小于等于nums[right],那么target肯定在后半区间,否则就是在前半区间。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        l, r = 0, len(nums) - 1
        
        while l <= r:
            mid = l + (r - l) // 2
            if nums[mid] == target:
                return mid
            
            if nums[mid] >= nums[l]:
                if target >= nums[l] and target < nums[mid]:
                    r = mid - 1
                else:
                    l = mid + 1
            else:
                if target > nums[mid] and target <= nums[r]:
                    l = mid + 1
                else:
                    r = mid - 1
        
        return -1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值