寻找两个正序数组的中位数
题目描述:
看到这个题时,就这??还困难题?直接数组合并排序找中位数就可以了嘛,然后我就遭到超时无情的打脸,hhhhhhhh
于是我就想了一个很笨重的做法,首先求中位数时,肯定是要排好序的一串数,然后要判断数的个数是奇数还是偶数,奇数取中间的数即可,偶数要取中间两个数的平均数,按照这个想法,便写了如下程序
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int i=0;
int j=0;
double result=0;
int surplus=0;
int list_l=0;
int all_length=nums1.length+nums2.length;
ArrayList<Integer> list=new ArrayList<>();
while(true){
if((i>=nums1.length)||(j>=nums2.length))
break;
if(nums1[i]<=nums2[j]){
list.add(nums1[i]);
i++;
}
else{
list.add(nums2[j]);
j++;
}
}
list_l=i+j;
if(all_length%2==1){
if(list_l<=all_length/2){
if(i<nums1.length)
result=(double)nums1[(all_length/2)+1-list_l+i-1];
else
result=(double)nums2[(all_length/2)+1-list_l+j-1];
}
else{
result=(double)list.get(all_length/2);
}
}
else{
if(list_l>all_length/2)
result=(double)(list.get(all_length/2-1)+list.get(all_length/2))/2;
else if(list_l==all_length/2){
if(i<nums1.length)
result=(double)(list.get(all_length/2-1)+nums1[i])/2;
else
result=(double)(list.get(all_length/2-1)+nums2[j])/2;
}
else if(list_l<all_length/2){
if(i<nums1.length)
result=(double)(nums1[all_length/2]-list_l+i-1+nums1[all_length/2]-list_l+i)/2;
else
result=(double)(nums2[all_length/2]-list_l+j-1+nums2[all_length/2]-list_l+j)/2;
}
}
return result;
}
首先使用一个循环来将两个正序数组合成一个正序list,但是这里有个处理,在合成一个list集合时顺便比较大小从而实现排序,这样会出现某一方先被安全加入到list集合中,此时我们停下来
之后我们先计算list集合的长度list_l,然后我们去判断一下两个正序数组的总长度all_length为奇数还是偶数:
奇数时:
中位数必定为某一个数字,这个时候去比较一下我们得到的集合list的长度和总长度的一半的大小,如果list集合长度大于总长度的一半那么中位数在list集合中取得,否则在没有完全加入到list集合中的数组中取得,此时要根据i,j与nums1.length和nums2.length分别比较判断是哪一个正序数组没有完全add到list集合中,如果是nums1,则中位数的下标为(all_length/2)+1-list_l+i-1
解释下这个:(all_length/2)+1是中位数的实际位置减去list_l后是指在数组nums1中剩余的数字中的第几个数字,加上i-1就是这个数字在nums1中的实际下表,取出这个数字即可
偶数时:
此时中位数为两个数的平均数,这个时候就有三种情况
1、这两个数字全在list集合中
2、这两个数字一个在list集合,另一个在剩余的没有加到集合的数字中
3、两个数字均在剩余的没有加到集合的数字中
之后取出这两个数求平均值即可
方法可读性比较差,可能不太好看懂,不过确实通过了此题