分治法-衆數問題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中含有多個具有相同重數的衆數,那這個代碼是解決不了這個問題的。這個坑以後再填。
接下來的時間會繼續實現有關分治法的幾個較爲經典的題目!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章