分治法之——两个已排序数组的中位数问题——Java实现

1. 问题描述

  设X[ 0 : n - 1]和Y[ 0 : n – 1 ]为两个数组,每个数组中含有n已排好序的数。找出X和Y的2n个数的中位数,如果中位数是两个,则取较小的一个。

2. 编程任务

  利用分治策略试设计一个O (log n)时间的算法求出这2n个数的中位数。

3. 问题分析

  首先,问题可以分为两类情况:① 其中一个数组的数都不比另一个小(记为X≥Y);② 两个数组都存在一些数比另一个数组里的大。

  对于第一种情况,可以很简单地得出结果,结果就是Y数组中最大的一个数。

  对于第二种情况,就需要判断两个数组的中位数。假设X的中位数比Y的大,则取X的前半部分、Y的后半部分,继续查找。针对得到的两个新数组,仍然采用上述方法进行判断,直到X和Y都只有一个数,此时取较小数作为最终结果,问题解决。

4. 代码实现

  下面只给出了实现算法的类MedianProblem的代码,测试代码就不贴了,因为涉及文件读写,太累赘。

package DC;

public class MedianProblem {

    private int[] x;
    private int[] y;

    public MedianProblem(int x[], int y[]){
        this.x = x;
        this.y = y;
    }

    public int getMid(){

        int l1 = 0, l2 = 0;
        int r1 = x.length-1, r2 = y.length-1;
        int i = x.length/2, j = y.length/2;

        while ((l1<=r1) && (l2<=r2)){
            if (x[r1] <= y[l2])//x的最大元素不比y的最小元素大,即整个y都比x大或相等
                return x[r1];
            if (x[l1] >= y[r2])//y的最大元素不比x的最小元素大,即整个x都比y大或相等
                return y[r2];
            if (x[i] == y[j])//子问题中,x的中位数与y的中位数相等
                return x[i];//直接返回中位数
            if (x[i] < y[j]) {//子问题中,x的中位数比y的中位数小,则在x的后半部分、y的前半部分查找
                l1 = i;
                i = (l1 + r1)/2;//将x设置为其后半部分
                r2 = j;
                j = (r2 + l2)/2;//将y设置为其前半部分
            } else{//子问题中,x的中位数比y的中位数大,则在x的前半部分、y的后半部分查找
                r1 = i;
                i = (r1 + l1)/2;//将x设置为其前半部分
                l2 = j;
                j = (l2 + r2)/2;//将y设置为其后半部分
            }
            if (l1==r1)//x到达了最后一个元素
                return x[l1];
            if (l2==r2)//y到达了最后一个元素
                return y[l2];

        }
        return -1;
    }
}

 

你可能感兴趣的:(Java实现,自己的代码,算法)