📜  两个有序数组的第 K 个元素(1)

📅  最后修改于: 2023-12-03 14:48:53.133000             🧑  作者: Mango

两个有序数组的第 K 个元素

在求解两个有序数组的第 K 个元素问题时,我们通常可以采取的方法有暴力枚举、归并排序、二分查找等算法。

暴力枚举

暴力枚举的思路很简单:我们从两个数组的头开始,比较它们的元素大小,将较小的元素插入到结果数组中,依次遍历直到找到第 K 个元素。

def kthElement(nums1, nums2, k):
    nums = nums1 + nums2    # 合并两个数组
    nums.sort()             # 排序数组
    return nums[k-1]        # 返回第 k 个元素

暴力枚举的时间复杂度为 $O(nlogn)$,其中 n 表示两个数组的长度之和。

归并排序

对于两个有序数组的问题,归并排序的思路是十分适用的。我们可以采用归并排序的方式合并两个有序数组,并在合并的过程中寻找第 K 个元素。

class Solution:
    def findKth(self, nums1, nums2, k):
        i, j, cnt = 0, 0, 0           # 初始化索引和计数器
        while i < len(nums1) and j < len(nums2):
            if nums1[i] < nums2[j]:
                cnt += 1
                if cnt == k: return nums1[i]
                i += 1
            else:
                cnt += 1
                if cnt == k: return nums2[j]
                j += 1
        while i < len(nums1):
            cnt += 1
            if cnt == k: return nums1[i]
            i += 1
        while j < len(nums2):
            cnt += 1
            if cnt == k: return nums2[j]
            j += 1

归并排序的时间复杂度为 $O(n)$,其中 n 表示两个数组的长度之和。

二分查找

对于已排序的数组,可以采用二分查找的方式寻找第 K 个元素。我们可以查询两个数组中间的元素,比较它们的大小,然后舍去较小的一半,继续在剩余的一半中查找,直到找到第 K 个元素。

class Solution:
    def findKth(self, nums1, nums2, k):
        len1, len2 = len(nums1), len(nums2)
        if len1 > len2:
            nums1, nums2, len1, len2 = nums2, nums1, len2, len1
        left, right = 0, len1    # 初始化左右边界
        while left <= right:
            mid1 = (left + right) // 2           # 在 nums1 中查找的索引
            mid2 = k - mid1 - 1                  # 在 nums2 中查找的索引
            if mid2 >= len2 or nums1[mid1] >= nums2[mid2] if mid2 >= 0 else True:
                if mid1 == 0 or nums2[mid2] >= nums1[mid1-1]:
                    return nums1[mid1]          # 中位数在 nums1[mid1] 或 nums2[mid2] 中
                right = mid1 - 1
            else:
                left = mid1 + 1
        return -1   # 如果找不到第 K 个元素,则返回 -1

二分查找的时间复杂度为 $O(logn)$,其中 n 表示两个数组的长度之和。

以上就是三种解决两个有序数组的第 K 个元素问题的方法,各有优劣。在实际应用中,我们需要根据具体情况进行选择。