本文共 1725 字,大约阅读时间需要 5 分钟。
题目大意是给定两个有序数组 nums1 和 nums2,要求找到它们合并后的中位数,并且要保证算法的时间复杂度为 O(log(m + n)),其中 m 和 n 分别是两个数组的长度。
中位数是两个数组合并后按照大小顺序排列后的中间值。对于偶数个元素的情况,中位数是中间两个数的平均值。对于奇数个元素,则是中间的那个数。
常规的解法是将两个数组合并后进行排序,然后找到中间的元素。然而,这种方法的时间复杂度为 O(m + n),无法满足题目要求的 O(log(m + n)) 高效率。
我们需要通过二分查找的方法来找到两个有序数组中的中位数。具体思路如下:
确定中位数的位置
首先,计算两个数组的总长度的中位数位置 k。在两个数组中同时查找第 k 小的元素
我們需要同时在 nums1 和 nums2 中查找第 k 小的元素。计算中位数
然后将两个数组中第 k 小的元素相加,取平均值即可得到中位数。public double findMedianSortedArrays(int[] nums1, int[] nums2) { int n = nums1.length; int m = nums2.length; int left = (n + m + 1) / 2; int right = (n + m + 2) / 2; int k1 = getKth(nums1, 0, n - 1, nums2, 0, m - 1, left); int k2 = getKth(nums1, 0, n - 1, nums2, 0, m - 1, right); return (k1 + k2) * 0.5;}private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) { int len1 = end1 - start1 + 1; int len2 = end2 - start2 + 1; if (len1 > len2) { return getKth(nums2, start2, end2, nums1, start1, end1, k); } if (len1 == 0) { return nums2[start2 + k - 1]; } if (k == 1) { return Math.min(nums1[start1], nums2[start2]); } int i = start1 + (Math.min(len1, k / 2) - 1); int j = start2 + (Math.min(len2, k / 2) - 1); if (nums1[i] > nums2[j]) { return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1)); } else { return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1)); }} 转载地址:http://rmhqz.baihongyu.com/