给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { /* 寻找中位数,可以看成寻找一条分割线,使分割线两侧,左边小于右边 * 当数组长度为奇数时,我们让左边元素多一个,则此时,中位数为左边两个最大数的最大值 * 当数组长度为偶数时,中位数为左边最大值和右边最小值的平均数 */ // 为了使第二个数组右边总是有值,当nums1长度大于nums2长度时,我们交换两个引用 if(nums1.length > nums2.length) { int[] temp = nums1; nums1 = nums2; nums2 = temp; } // 左边所有元素需要满足的个数 int totalLeft = (nums1.length + nums2.length + 1) / 2; // 分割线寻找的左右边界 int left = 0, right = nums1.length; while(left < right) { // 取左右边界平均(二分)作为i,则第二个数组左边元素个数为j // 加1为了两个元素时不进入死循环 int i = (left + right + 1) / 2, j = totalLeft - i; // 数组1左边最大值的数值大于数组2右边最小值,此时分割线需要左移 if (nums1[i - 1] > nums2[j]) { right = i - 1; } else { // 反面 left = i; } } // 重新定义分割线 int i = left, j = totalLeft - i; // 分别得到nums1 nums2左边最大值和右边最小值(需要考虑边界情况) int nums1LeftMax = i == 0 ? Integer.MIN_VALUE : nums1[i - 1]; int nums1RightMin = i == nums1.length ? Integer.MAX_VALUE : nums1[i]; int nums2LeftMax = j == 0 ? Integer.MIN_VALUE : nums2[j - 1]; int nums2RightMin = j == nums2.length ? Integer.MAX_VALUE : nums2[j]; // 数组长度为奇数,返回左边最大值,偶数返回左边最大值和右边最小值的平均数 if ((nums1.length + nums2.length) % 2 == 1) { return Math.max(nums1LeftMax, nums2LeftMax); } else { return (double)(Math.max(nums1LeftMax, nums2LeftMax) + Math.min(nums1RightMin, nums2RightMin)) / 2; } } }