分治法-眾數問題java實現
阿新 • • 發佈:2018-12-09
先挖個坑,兩天之內必現程式碼(畢竟我在網上很難找到真正用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中含有多個具有相同重數的眾數,那這個程式碼是解決不了這個問題的。這個坑以後再填。 接下來的時間會繼續實現有關分治法的幾個較為經典的題目!