分治法-众数问题java实现

先挖个坑,两天之内必现代码(毕竟我在网上很难找到真正用java实现的)

来填坑了,众数问题的分治法java实现。
首先说一下其他的思路
1.暴力法:选取其中的每个数遍历,得到每个数的重复次数,进行比较,O(n2)
2.先进行排序,O(nlgn),再去找,O(n)
3.使用额外空间(数组或者是哈希表)时间复杂度O(n),空间O(n),但是在用数组时如果数的跨度较大,比如:{1,1,1,1,1,1000000000000000000000000},这种就太不划算了。
4.分治法:
首先使用荷兰国旗问题的划分方法将数组划分为三个部分,O(n)
然后得到等于部分的重复个数largest,并与左右两边比较
如果largest>=左边个数,左边舍弃,反之左边继续递归,
右边同理
上代码:
这里要说明的是,IntHolder是java中用于参数传递的一个类。因为本菜鸡此次的代码是通过王晓东算法四版书上的c代码改编,c代码中有引用参数传递的过程,在函数运行中可以不断代表参数largest的值,但是java中没得。所以找到了这样一个类。先贴一下它的用法:

public class valueTran {
    public static void trip(IntHolder i)
    {
        i.value = i.value+3;
    }

    public static void main(String[] args) {
        IntHolder aHolder = new IntHolder();
        aHolder.value= 10;
        trip(aHolder);
        System.out.println(aHolder.value);
        }
}

输出13

一下是分治法实现众数问题的代码,如有问题多多指教。

public class Mode {

    public static int mode(int[] a,int l,int r,IntHolder largest) {

        IntHolder l1=new IntHolder();
        IntHolder r1=new IntHolder();
        int med=median(a, l, r);
        split(a, l, r, l1, r1, med);
        if(largest.value<r1.value-l1.value+1) {
            largest.value=r1.value-l1.value+1;
        }
        System.out.println("largest:"+largest.value);
        if(l1.value-l>largest.value) {
            mode(a, l, l1.value-1, largest);
        }
        if(r-r1.value>largest.value) {
            mode(a, r1.value+1, r, largest);
        }
        return largest.value;
    }
    public static  void split(int[] arr,int L,int R,IntHolder l1,IntHolder r1,int key) {
        int less=L-1,more=R+1;

        while(L<more) {
            if(arr[L]<key) {
                swap(arr, L++, ++less);
            }else if(arr[L]>key) {
                swap(arr, L,--more);
            }else {
                L++;
            }
        }
        for(int i=0;i<arr.length;i++) {
            System.out.print(arr[i]+",");
        }
        System.out.println();
        System.out.print("less+1="+(less+1)+",more-1="+(more-1));
        System.out.print(",key="+key);
        l1.value=less+1;
        r1.value=more-1;
    }
    public static void swap(int[] arr,int l,int r) {
        int temp=arr[l];
        arr[l]=arr[r];
        arr[r]=temp;
    }
    public static int median(int[] arr,int l,int r) {
        int mid=(l+r)/2;
        return arr[mid];
    }
    public static void main(String[] args) {
        int[] arr= {1,2,2,2,2,2,3,1,3,1,1,1,3,5,2,6,7};
        int key=median(arr, 0, arr.length-1);
        System.out.println("key="+key);
        int count=0;
        IntHolder l1,r1;
        l1=new IntHolder();
        r1=new IntHolder();
        split(arr, 0, arr.length-1,l1,r1,key);
        System.out.println(",l1="+l1.value+",r1="+r1.value);
        System.out.println("----------------------------------------");
        IntHolder largest=new IntHolder();
        largest.value=0;
        System.out.println("===="+mode(arr, 0, arr.length-1, largest));
    }
}

貌似还有点问题,就是如果集合s中含有多个具有相同重数的众数,那这个代码是解决不了这个问题的。这个坑以后再填。
接下来的时间会继续实现有关分治法的几个较为经典的题目!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值