题目描述

原题链接

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。

进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

示例 1:

  1. 输入:nums1 = [1,3], nums2 = [2]
  2. 输出:2.00000
  3. 解释:合并数组 = [1,2,3] ,中位数 2

示例 2:

  1. 输入:nums1 = [1,2], nums2 = [3,4]
  2. 输出:2.50000
  3. 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

示例 3:

  1. 输入:nums1 = [0,0], nums2 = [0,0]
  2. 输出:0.00000

示例 4:

  1. 输入:nums1 = [], nums2 = [1]
  2. 输出:1.00000

示例 5:

  1. 输入:nums1 = [2], nums2 = []
  2. 输出:2.00000

提示:

  • nums1.length == m
  • nums2.length == n
  • 0 <= m <= 1000
  • 0 <= n <= 1000
  • 1 <= m + n <= 2000
  • -106 <= nums1[i], nums2[i] <= 106

个人解法

Java

JavaScript

  1. /**
  2. * @param {number[]} nums1
  3. * @param {number[]} nums2
  4. * @return {number}
  5. */
  6. var findMedianSortedArrays = function(nums1, nums2) {
  7. var len1 = nums1.length;
  8. var len2 = nums2.length;
  9. var nums2Index = 0;
  10. var arr = nums1;
  11. for (var i = 0; i < len2; i++) {
  12. var j = 0;
  13. while (j < len1) {
  14. if (arr[j] > nums2[i]) {
  15. arr.splice(j, 0, nums2[i]);
  16. nums2Index++;
  17. len1++;
  18. break;
  19. }
  20. j++;
  21. }
  22. }
  23. if (nums2Index < len2) {
  24. for (var i = nums2Index; i < len2; i++) {
  25. arr.push(nums2[i]);
  26. len1++;
  27. }
  28. }
  29. var result = (arr[Math.floor((len1 - 1) / 2)] + arr[Math.ceil((len1 - 1) / 2)]) / 2;
  30. return len1 ? result : 0;
  31. };

更优解法

Java

JavaScript

  1. /**
  2. * 二分解法
  3. * @param {number[]} nums1
  4. * @param {number[]} nums2
  5. * @return {number}
  6. */
  7. var findMedianSortedArrays = function(nums1, nums2) {
  8. // make sure to do binary search for shorten array
  9. if (nums1.length > nums2.length) {
  10. [nums1, nums2] = [nums2, nums1]
  11. }
  12. const m = nums1.length
  13. const n = nums2.length
  14. let low = 0
  15. let high = m
  16. while(low <= high) {
  17. const i = low + Math.floor((high - low) / 2)
  18. const j = Math.floor((m + n + 1) / 2) - i
  19. const maxLeftA = i === 0 ? -Infinity : nums1[i-1]
  20. const minRightA = i === m ? Infinity : nums1[i]
  21. const maxLeftB = j === 0 ? -Infinity : nums2[j-1]
  22. const minRightB = j === n ? Infinity : nums2[j]
  23. if (maxLeftA <= minRightB && minRightA >= maxLeftB) {
  24. return (m + n) % 2 === 1
  25. ? Math.max(maxLeftA, maxLeftB)
  26. : (Math.max(maxLeftA, maxLeftB) + Math.min(minRightA, minRightB)) / 2
  27. } else if (maxLeftA > minRightB) {
  28. high = i - 1
  29. } else {
  30. low = low + 1
  31. }
  32. }
  33. };