返回

深入解析LeetCode旋转数组系列:153、154、33和81

后端







**导语** 

LeetCode是一个著名的在线编程题库,上面有许多高质量的算法题。旋转数组系列是LeetCode上一个比较经典的题目系列,其中包括1531543381这四道题目。这些题目都与旋转数组相关,但题目的条件限制有所不同。旋转数组是指将一个按升序排列好的数组,往右侧循环移位,使得整个数组形成左右两个有序区间,且左区间的数都比右区间的数大。

**题目分析** 

这四道题目的主要区别在于给定的旋转数组的条件不同。

* 153. 寻找旋转排序数组中的最小值:给定一个旋转排序数组,找出数组中的最小值。
* 154. 寻找旋转排序数组中的最大值:给定一个旋转排序数组,找出数组中的最大值。
* 33. 搜索旋转排序数组:给定一个旋转排序数组和一个目标值,找出目标值在数组中的位置。
* 81. 搜索旋转排序数组 II:给定一个旋转排序数组和一个目标值,找出目标值在数组中出现的次数。

**解题思路** 

这四道题目都可以使用二分查找的思想来解决。二分查找是一种在有序数组中快速查找元素的算法。二分查找的原理是,每次将数组一分为二,然后根据目标值与中间元素的大小关系来决定继续查找数组的哪一半。如此反复,直到找到目标值或确定目标值不在数组中。

**代码示例** 

```python
def find_min(nums):
    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]

def find_max(nums):
    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[right]

def search(nums, target):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

def search_range(nums, target):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] == target:
            left = mid
            right = mid
            while left >= 0 and nums[left] == target:
                left -= 1
            while right < len(nums) and nums[right] == target:
                right += 1
            return [left + 1, right - 1]
        elif nums[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return [-1, -1]

总结

LeetCode旋转数组系列的这四道题目都是非常经典的算法题,它们可以帮助我们提高自己的算法和数据结构能力。通过学习这些题目,我们可以掌握二分查找的基本原理和应用方法,为面试和编程竞赛做好准备。