给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。
- 示例 1:输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2
- 示例 2:输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) /2 = 2.5
- 示例 3:输入:nums1 = [0,0], nums2 = [0,0] 输出:0.00000
- 示例 4:输入:nums1 = [], nums2 = [1] 输出:1.00000
- 示例 5:输入:nums1 = [2], nums2 = [] 输出:2.00000
提示:
nums1.length == m nums2.length == n 0 <= m <= 1000 0 <= n <= 1000 1 <= m + n<= 2000 -106 <= nums1[i], nums2[i] <= 106
进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?(我表示没有做到)
class Test4 {/*** 直接用归并排序来做排序,然后取中位数即可* 执行用时:78 ms, 在所有 Java 提交中击败了5.14%的用户 内存消耗:39.8 MB, 在所有 Java 提交中击败了33.73%的用户* 扎心,看来排序不靠谱O(N*lgN)*/public double findMedianSortedArrays(int[] nums1, int[] nums2) {// 设置中位数的值double result = 0d;if (nums1.length == 0 && nums2.length == 0) {return result;}// 对左边进行归并排序mergeSort(nums1, 0, nums1.length - 1);System.out.println("nums1排序之后:");for (int i = 0; i < nums1.length; i++) {System.out.print(nums1[i] + " ");}// 对右边进行归并排序mergeSort(nums2, 0, nums2.length - 1);System.out.println("nums2排序之后:");for (int i = 0; i < nums2.length; i++) {System.out.print(nums2[i] + " ");}// 对两边进行合并int[] nums = new int[nums1.length + nums2.length];mergeNums1Nums2(nums, nums1, nums2);System.out.println("nums排序之后:");for (int i = 0; i < nums.length; i++) {System.out.print(nums[i] + " ");}// 取中位数int mid = nums.length / 2;if (nums.length % 2 == 0) {// 表明是偶数,取中间的和上一个相加result = (nums[mid] + nums[mid - 1]) / 2d;} else {result = nums[mid];}System.out.println("中位数:" + result);return result;}private void mergeNums1Nums2(int[] nums, int[] nums1, int[] nums2) {int nums1_left = 0;int nums1_right = nums1.length - 1;int nums2_left = 0;int nums2_right = nums2.length - 1;int now = 0;while (nums1_left <= nums1_right && nums2_left <= nums2_right) {// 从两个数组中选取较小的数放入中间数组if (nums1[nums1_left] <= nums2[nums2_left]) {nums[now] = nums1[nums1_left];nums1_left++;} else {nums[now] = nums2[nums2_left];nums2_left++;}now++;}// 将剩余的部分放入中间数组while (nums1_left <= nums1_right) {nums[now] = nums1[nums1_left];nums1_left++;now++;}while (nums2_left <= nums2_right) {nums[now] = nums2[nums2_left];nums2_left++;now++;}}private void mergeSort(int[] a, int left, int right) {if (left < right) {int middle = (left + right) / 2;// 对左边进行递归mergeSort(a, left, middle);// 对右边进行递归mergeSort(a, middle + 1, right);// 合并merge(a, left, middle, right);}}private void merge(int[] a, int left, int middle, int right) {int[] tmpArr = new int[a.length];int mid = middle + 1; // 右边的起始位置int tmp = left;int third = left;while (left <= middle && mid <= right) {// 从两个数组中选取较小的数放入中间数组if (a[left] <= a[mid]) {tmpArr[third++] = a[left++];} else {tmpArr[third++] = a[mid++];}}// 将剩余的部分放入中间数组while (left <= middle) {tmpArr[third++] = a[left++];}while (mid <= right) {tmpArr[third++] = a[mid++];}// 将中间数组复制回原数组while (tmp <= right) {a[tmp] = tmpArr[tmp++];}}public static void main(String[] args) {int[] num1 = { 1, 2 };int[] num2 = { 3, 4 };new Test4().findMedianSortedArrays(num1, num2);}}
丢人,超过的人太少了!
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
