ps:题目来自力扣
寻找两个正序数组的中位数
给定两个大小分别为 m
和 n
的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n))
。
class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {// 为了让二分查找的范围更小,保证 nums1 是较短的数组if (nums1.length > nums2.length) {int[] temp = nums1;nums1 = nums2;nums2 = temp;}int m = nums1.length;int n = nums2.length;// 左半部分的元素数量,无论两数组总长度奇偶,左半部分元素数量为 (m + n + 1) / 2int totalLeft = (m + n + 1) / 2;// 二分查找的左右边界,在 nums1 的索引 0 到 m 之间查找分割线int left = 0;int right = m;while (left < right) {// nums1 的分割线位置int i = left + (right - left + 1) / 2;// nums2 的分割线位置,根据 left 部分元素总数确定int j = totalLeft - i;// 如果 nums1 分割线左边的元素大于 nums2 分割线右边的元素if (nums1[i - 1] > nums2[j]) {// 说明分割线 i 太靠右了,需要向左移动right = i - 1;} else {// 分割线 i 合适或者还可以往右移动left = i;}}// 最终确定的 nums1 分割线位置int i = left;// 最终确定的 nums2 分割线位置int j = totalLeft - i;// 计算分割线左右的四个关键元素int nums1LeftMax = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];int nums1RightMin = (i == m) ? Integer.MAX_VALUE : nums1[i];int nums2LeftMax = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];int nums2RightMin = (j == n) ? Integer.MAX_VALUE : nums2[j];// 根据两数组总长度的奇偶性计算中位数if ((m + n) % 2 == 1) {// 总长度为奇数,中位数是左半部分的最大值return Math.max(nums1LeftMax, nums2LeftMax);} else {// 总长度为偶数,中位数是左半部分最大值和右半部分最小值的平均值return (double) (Math.max(nums1LeftMax, nums2LeftMax) + Math.min(nums1RightMin, nums2RightMin)) / 2;}}
}