参考Mini_Coconut的博客,网址:https://www.cnblogs.com/mini-coconut/p/9066508.html
【004-Median of Two Sorted Arrays(两个排序数组的中位数)】
一、概念
中位数:一组数据从小到大排列中间的那个数字。如果是偶数的话,就是中间两个数字相加除以2.
代码如下:
package algorithm;
import java.util.Vector;
//https://www.cnblogs.com/mini-coconut/p/9066508.html
public class Median {
//---自定义书写
//两个排序数组的中位数
public int findMedianBySortedArrays(Vector<Integer> list1,Vector<Integer> list2){
Vector<Integer> list=new Vector<Integer>();
//重新排序,其中list1和list2是已排序的数组
int i=0,j=0;
while(i<list1.size()&&j<list2.size()){
if(list1.get(i)<list2.get(j)){
list.add(list1.get(i++));
}else{
list.add(list2.get(j++));
}
}
if(i<list1.size()){
while(i<list1.size()){
list.add(list1.get(i++));
}
}
if(j<list2.size()){
while(j<list2.size()){
list.add(list2.get(j++));
}
}
int size=list.size()%2;
vectorPrint(list);
int num=list.size();
if(size==0){ //偶数
System.out.println("偶数");
return (list.get(num/2)+list.get(num/2-1))/2;
}else{ //奇数
System.out.println("奇数");
return list.get(num/2);
}
}
public void vectorPrint(Vector<Integer> list){
if(list==null){
return;
}
System.out.println("---------------------");
for(int i=0;i<list.size();i++){
int tmp=list.get(i);
System.out.print(tmp+"-");
}
System.out.println();
System.out.println("---------------------");
}
/*
* 从已排序的2个数组中,查找第k个小的数字
* 参数:i和j分别是list1和list2的起始位置
*
* */
public int findMedianNum(Vector<Integer> list1,int i,Vector<Integer> list2,int j,int k){
//让数组1的长度小于或等于数组2的长度
if(list1.size()-i>list2.size()-j){
return findMedianNum(list2,j,list1,i,k);
}
//判断数组小的是否为空,如果为空,则直接在另一个数组查找
if(list1.size()==i){//list1为空,直接查找第k个
return list2.get(k+j-1);
}
if(k==1){//查找第一个元素
return min(list1.get(i),list2.get(j));
}
//假设list1和list2都大于k/2,如果A[k/2-1]与B[k/2-1], A[0],A[1],,,A[k/2-1],即此为k/2
//同时B[k/2-1],此为B[0],B[1],,,B[k/2-1],即此为k/2,如果A[k/2-1]<B[k/2-1],则A[k/2-1]小于合并后的
//第k个值。
//数组1中需要查询的第k/2个数
int pa=min(k/2+i,list1.size());
//此时数组1中含有元素个数为pa-i,只需比较数组1和数组2中正好元素为k既可,
//数组2中元素个数为pb-j。一共应为k=pa-i+pb-j
int pb=k+j+i-pa;
//所以,pb=k+j+i-pa
if(list1.get(pa-1)<list2.get(pb-1)){//数组1第k/2小于数组2中,则数组1中k/2以前的元素均可排除,不是第k个数
//i,i+1,,,pa-1,共有元素个数为: pa-1-(i-1)=pa-i
return findMedianNum(list1,pa,list2,j,k-pa+i);
}else if(list1.get(pa-1)>list2.get(pb-1)){//此时pb前的元素均不可为在第k个元素
//j,j+1,,,pb-1,剩余为pb-1-(j-1)=pb-j 个元素无用
return findMedianNum(list1,i,list2,pb,k-pb+j);
}else{//相等,此时即为第k个元素
return list1.get(pa-1);
}
}
/*
* 查找最小值
* */
public int min(int i,int j){
if(i<j){
return i;
}else{
return j;
}
}
/*
* 查找最大值
* */
public int max(int i,int j){
if(i>j){
return i;
}else{
return j;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Vector<Integer> list1=new Vector<Integer>();
list1.add(10);
list1.add(30);
list1.add(50);
list1.add(70);
list1.add(90);
Vector<Integer> list2=new Vector<Integer>();
list2.add(20);
list2.add(40);
list2.add(60);
list2.add(80);
//list2.add(100);
int result=new Median().findMedianBySortedArrays(list1,list2);
System.out.println("结果是="+result);
int num1=list1.size();
int num2=list2.size();
//num1与num2均不为空
int total=num1+num2;
int result2=0;
if(total%2==1){//奇数个
result2=new Median().findMedianNum(list1, 0, list2, 0, total/2+1);
}else{
result2=(new Median().findMedianNum(list1, 0, list2, 0, total/2)+new Median().findMedianNum(list1, 0, list2, 0, total/2+1))/2;
}
System.out.println("结果为:"+result2);
}
}