给定两个大小分别为 m
和 n
的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n))
。
:本题难点在于时间复杂度的掌握,
思路:把两个数组合为一个数组因为要找中位数,只用合到中间位置其余部分直接不用管,详细点说:
- 合并数组: 将两个已排序的数组合并成一个单一的有序数组。可以使用两个指针分别指向两个数组的开头,比较两个指针所指的元素,将较小的元素加入合并后的数组,然后移动相应的指针。
- 计算中位数: 根据数组的长度,确定中位数的位置。如果数组长度之和为奇数,则中位数是中间的元素;如果长度之和为偶数,则中位数是中间两个元素的平均值。
下面是一个更详细的步骤:
- 初始化两个指针
i
和j
分别指向两个数组的开头。 - 使用一个额外数组(或在原数组上进行合并)存储合并后的结果。
- 比较
nums1[i]
和nums2[j]
,将较小的元素加入结果数组,并移动相应的指针。 - 重复上述步骤,直到其中一个数组的所有元素都被合并。
- 如果数组长度之和为奇数,中位数即为结果数组的中间元素。
- 如果数组长度之和为偶数,中位数即为结果数组的中间两个元素的平均值。
这个算法的时间复杂度是 O(m + n),其中 m 和 n 分别是两个数组的长度。
class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {// 获取数组长度int m = nums1.length, n = nums2.length;// 定义指针 i, j 和合并数组的指针 sint i = 0, j = 0, s = 0;// 创建一个数组用于存储两个有序数组的合并结果double[] nums = new double[n + m];// 合并两个有序数组while (i < m && j < n && s <= (m + n) / 2) {// 比较当前两个数组元素,将较小的值放入合并数组if (nums2[j] <= nums1[i]) {nums[s] = nums2[j];j = j + 1;s = s + 1;} else {nums[s] = nums1[i];i = i + 1;s = s + 1;}}// 处理其中一个数组已经遍历完的情况while (i == m && j < n && s <= (m + n) / 2) {nums[s] = nums2[j];s = s + 1;j = j + 1;}while (j == n && i < m && s <= (m + n) / 2) {nums[s] = nums1[i];s = s + 1;i = i + 1;}// 计算中位数double x = 0;if ((m + n) % 2 == 0) // 如果数组长度之和为偶数x = (nums[(m + n) / 2] + nums[(m + n) / 2 - 1]) / 2;else // 如果数组长度之和为奇数x = nums[(m + n) / 2];// 返回中位数return x;}
}
`
运行时间:1ms