寻找两个正序数组的中位数

给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数

算法的时间复杂度应该为 O(log (m+n))

:本题难点在于时间复杂度的掌握,

思路:把两个数组合为一个数组因为要找中位数,只用合到中间位置其余部分直接不用管,详细点说:

  1. 合并数组: 将两个已排序的数组合并成一个单一的有序数组。可以使用两个指针分别指向两个数组的开头,比较两个指针所指的元素,将较小的元素加入合并后的数组,然后移动相应的指针。
  2. 计算中位数: 根据数组的长度,确定中位数的位置。如果数组长度之和为奇数,则中位数是中间的元素;如果长度之和为偶数,则中位数是中间两个元素的平均值。

下面是一个更详细的步骤:

  • 初始化两个指针 ij 分别指向两个数组的开头。
  • 使用一个额外数组(或在原数组上进行合并)存储合并后的结果。
  • 比较 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 和合并数组的指针 s
        int 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

你可能感兴趣的:(算法,数据结构,leetcode,java)