2个排序数组的中位数

参考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);
        
    }

}
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值