📌  相关文章
📜  查找排序和旋转数组中的最小元素(1)

📅  最后修改于: 2023-12-03 15:10:44.811000             🧑  作者: Mango

查找排序和旋转数组中的最小元素

在排序数组中查找最小元素是一个很常见的问题。当数组经过旋转后,问题变得有些复杂。在本文中,我们将介绍如何在排序和旋转数组中查找最小元素,并给出相应的代码。

在排序数组中查找最小元素

对于一个排序数组,我们可以很容易地找到最小元素。一般的思路是使用二分查找。

具体地,我们考虑数组的中间元素mid,与数组的最后一个元素end比较,有以下两种情况:

  • nums[mid] < nums[end],则mid在左半边有序区间中,此时最小元素在mid的左边,我们可以将end指向mid;
  • nums[mid] > nums[end],则mid在右半边有序区间中,此时最小元素在mid的右边,我们可以将start指向mid + 1。

代码如下:

def findMin(nums: List[int]) -> int:
    n = len(nums)
    start, end = 0, n - 1
    while start < end:
        mid = (start + end) // 2
        if nums[mid] < nums[end]:
            end = mid
        else:
            start = mid + 1
    return nums[start]

时间复杂度为$O(\log n)$,空间复杂度为$O(1)$。

在旋转数组中查找最小元素

在旋转数组中查找最小元素,则需要考虑更多的情况。不过,我们仍然可以套用二分查找的思路。

具体地,我们考虑数组的中间元素mid和数组的最后一个元素end、第一个元素start比较,有以下三种情况:

  • nums[mid] < nums[end],此时mid在右半边有序区间中,最小元素在mid的左边,我们可以将end指向mid;
  • nums[mid] > nums[end],此时mid在左半边有序区间中,最小元素在mid的右边,我们可以将start指向mid + 1;
  • nums[mid] == nums[end],此时不能确定最小元素在哪个区间中,可以将end减1,继续查找。因为题目中规定的是数组不存在重复元素,所以我们不会将最小值漏掉。

代码如下:

def findMin(nums: List[int]) -> int:
    n = len(nums)
    start, end = 0, n - 1
    while start < end:
        mid = (start + end) // 2
        if nums[mid] < nums[end]:
            end = mid
        elif nums[mid] > nums[end]:
            start = mid + 1
        else:
            end -= 1
    return nums[start]

时间复杂度为$O(\log n)$,空间复杂度为$O(1)$。

总结

本文介绍了如何在排序和旋转数组中查找最小元素,并给出相应的代码。对于排序数组,我们可以使用二分查找,时间复杂度为$O(\log n)$,空间复杂度为$O(1)$。对于旋转数组,我们仍然可以使用二分查找,时间复杂度为$O(\log n)$,空间复杂度为$O(1)$。