给定两个大小分别为 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
暴力解法:
直接把两个数组变成一个顺序排列的数组,然后就很容易得到中位数O(n):
import java.util.Vector;
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int flat1=0,flat2=0;Vector<Integer> vector=new Vector<Integer>();double middle=0;
while(flat1<nums1.length&&flat2<nums2.length){
if(nums1[flat1]<=nums2[flat2]){
vector.add(nums1[flat1]);
flat1++;
}
else{
vector.add(nums2[flat2]);
flat2++;
}
}
if(flat1==nums1.length&&flat2!=nums2.length){
while (flat2!=nums2.length){
vector.add(nums2[flat2]);
flat2++;
}
}
if(flat2==nums2.length&&flat1!=nums1.length){
while(flat1!=nums1.length){
vector.add(nums1[flat1]);
flat1++;
}
}
int size=vector.size();
if(size%2==0){
middle=(vector.get(size / 2 - 1) + vector.get(size / 2))/2.0;
}else{
middle=vector.get(size/2);
}
return middle ;
}
}
当然,这肯定需要改进:
因为中位数的定义是排列的中间元素。所以就对比两个数组中最中间的元素的大小,如果左边的数组的中间元素比右边的小,那么左边的数组中位数旁边的就一定不是中位数,再不断遍历。
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int length1 = nums1.length, length2 = nums2.length;
int totalLength = length1 + length2;
if (totalLength % 2 == 1) {
int midIndex = totalLength / 2;
double median = getKthElement(nums1, nums2, midIndex + 1);
return median;
} else {
int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
return median;
}
}
public int getKthElement(int[] nums1, int[] nums2, int k) {
int length1 = nums1.length, length2 = nums2.length;
int index1 = 0, index2 = 0;
int kthElement = 0;
while (true) {
// 边界情况
if (index1 == length1) {
return nums2[index2 + k - 1];
}
if (index2 == length2) {
return nums1[index1 + k - 1];
}
if (k == 1) {
return Math.min(nums1[index1], nums2[index2]);
}
// 正常情况
int half = k / 2;
int newIndex1 = Math.min(index1 + half, length1) - 1;
int newIndex2 = Math.min(index2 + half, length2) - 1;
int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
if (pivot1 <= pivot2) {
k -= (newIndex1 - index1 + 1);
index1 = newIndex1 + 1;
} else {
k -= (newIndex2 - index2 + 1);
index2 = newIndex2 + 1;
}
}
}
}