第一种:暴力破解
将两个数组整合为一个数组,然后根据整合后数组的长度进行中位数的计算
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m=nums1.length,n=nums2.length;
int[] result=new int[m+n];
int flag=0,i=0,j=0;
while(m>i&&n>j){
if(nums1[i]<nums2[j]){
result[flag]=nums1[i];
i++;
flag++;
}
else{
result[flag]=nums2[j];
j++;
flag++;
}
}
if(i==m)
for(;j<n;j++,flag++)
result[flag]=nums2[j];
else
for(;i<m;i++,flag++)
result[flag]=nums1[i];
for(int k:result)
System.out.println(k);
System.out.println(result.length/2+" "+(result.length/2-1));
if(result.length%2==0)
return (result[result.length/2]+result[result.length/2-1])/2;
else
return result[result.length/2];
}
第二种:并不需要真的进行两个数组的合并,我们只需要找到中位数行营位置的数据就可以,即length/2以及length/2-1 对应位置的数据;
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m=nums1.length,n=nums2.length;
int i=0,j=0,flag=0,aim=(m+n)/2+1,pre=0,now=0;
while(flag<aim&&i<m&&j<n){
if(nums1[i]<=nums2[j]){
i++;
if(++flag<aim)
pre=nums1[i-1];
else
now=nums1[i-1];
}
else{
j++;
if(++flag<aim)
pre=nums2[j-1];
else
now=nums2[j-1];
}
System.out.println(now+" "+pre);
}
if(i==m&&flag<aim)
{
if(aim-flag<=1)
now=nums2[j+aim-flag-1];
else{
pre=nums2[j+aim-flag-2];
now=nums2[j+aim-flag-1];
}
}
else if(j==n&&flag<aim){
if(aim-flag<=1)
now=nums1[i+aim-flag-1];
else{
pre=nums1[i+aim-flag-2];
now=nums1[i+aim-flag-1];
}
}
System.out.println(now+" "+pre);
if((m+n)%2==0)
return (double)(now+pre)/2;
else
return now;
}
第三种:第k小解题
我们要找的中位数其实就是两个数组中的第length/2个小的数,如果将长度为奇数和长度为偶数的数组统一的话,我们可以得到下面的公式:
中位数=第length/2+1个小的数+第(length+1)/2个小的数(奇数会得到两个相同位置的数,而偶数则得到两个中间位置的数)。寻找第k小由于我们输入的是有序数组就变得很简单;
public int findK(int k,int[] nums1,int[] nums2){
int m=nums1.length,n=nums2.length;
int i=0,j=0;
while(k>=1){
if(m==0)
return nums2[j+k-1];
else if(n==0)
return nums1[i+k-1];
else if(k/2>m){
if(nums1[i+m-1]<nums2[j+m-1])
return nums2[j+k-m-1];
else
{
k-=m;
j+=m;
n-=m;
}
}
else if(k/2>n){
if(nums1[i+n-1]>nums2[j+n-1])
return nums1[i+k-n-1];
else
{
k-=n;
i+=n;
m-=n;
}
}
else if(k/2==0){
System.out.println(i);
if(i==nums1.length)
return nums2[j];
else if(j==nums2.length)
return nums1[i];
else
return nums1[i]<nums2[j]?nums1[i]:nums2[j];
}
else{
if(nums1[i+k/2-1]<nums2[j+k/2-1])
{
m-=k/2;
i+=k/2;
k-=k/2;
}
else
{
j+=k/2;
n-=k/2;
k-=k/2;
}
}
}
return 0;
}
第四种:根据中位数的性质
中位数的定义就向我们阐述了它的作用,用于将一个集合分割为两部分,根据这个定义我们可以将两个数组分割为两部分,不断的分割,直至我们找到中位数所在的位置(利用二分搜索);从而使得分割后的数组左侧的最大值小于等于右侧的最小值,如果为奇数,中位数就是左侧最大值,反之则为左侧最大值和右侧最小值之和除2;
public double getAim(int[] nums1,int[] nums2){
int iMin=0,iMax=nums1.length,halfLength=(nums1.length+nums2.length+1)/2;
while(iMin<=iMax){
int i=(iMin+iMax)/2;
int j=halfLength-i;
if(i<iMax&&nums1[i]<nums2[j-1])
{
iMin=i+1;
}
else if(i>iMin&&nums1[i-1]>nums2[j])
{
iMax=i-1;
}
else{
int leftMax=0;
if(i==0) leftMax=nums2[j-1];
else if(j==0) leftMax=nums1[i-1];
else leftMax=Math.max(nums1[i-1],nums2[j-1]);
System.out.println(leftMax);
if((nums1.length+nums2.length)%2!=0) return (double)leftMax;
int rightMax=0;
if(i==nums1.length) rightMax=nums2[j];
else if(j==nums2.length)rightMax=nums1[i];
else rightMax=Math.min(nums1[i],nums2[j]);
System.out.println(rightMax);
return (double)(leftMax+rightMax)/2;
}
}
return 0.0;
}