問題描述:對於給定的含有n個元素的無序序列,求這個序列中最大和次大的兩個不同元素。
問題求解分析(分治法):先給出無序序列數組a[low...high]。第一種情況為當數組中只有一個元素時,此時只存在一個最大值即為本身,次大值為負無窮,在這里我設置為-999999,第二種情況為數組中只有兩個元素,此時最大值和次大值很顯然將兩個元素比較即可。第三種情況為數組中的元素大於兩個,此時用分治法,將數組中元素砍為兩半,像我們將香腸折半,注意的是此時中間的點歸為前半部分,接着我們對前半部分再次進行判斷三種情況,再對后半部分做同樣的操作,因為我們每次判斷返回的都是當前判斷的一部分的最大值和次大值,因此折半后兩邊都有最大值和次大值,再將兩邊的四個值比較找出最大值和次大值。
代碼如下:
import java.util.*; public class Main { static int a[];//存放數據的數組 static int inf=-999999;//自定義最小值 public static void main(String args[]) { a=new int[5]; a[0]=4;a[1]=3;a[2]=5;a[3]=9;a[4]=1;//測試數據,可修改為鍵盤輸入 max m=solve(0,4);//調用solve方法求出最大值和次大值 System.out.println(m.max1+" "+m.max2);//輸出 } static class max//自定義類(存放最大和次大值) { int max1;//最大值 int max2;//次大值 max(){};//構造函數 } static max solve(int low,int high)//low和high為數組中的起始下標和終止下標 { max mm=new max();//聲明,因為每次尋找返回的最大值和次大值都要更新 if(low==high)//如果只有一個元素 { mm.max1=a[low];//最大值為本身 mm.max2=inf;//次大值為inf } else if(low==high-1)//如果只有兩個元素 { mm.max1=Math.max(a[low], a[high]);//最大值為兩個元素中的最大值 mm.max2=Math.min(a[low], a[high]);//最小值為兩個元素中的最小值 } else//大於兩個元素 { int mid=(low+high)/2;//設中間值為mid max m1=solve(low,mid);//m1為前半部分的最大值和次大值(包括a[mid]) max m2=solve(mid+1,high);//m2為后半部分的最大值和次大值 if(m1.max1>m2.max1)//如果前半部分最大值大於后半部分最大值 { mm.max1=m1.max1;//更新最大值為前半部分最大值 mm.max2=Math.max(m1.max2,m2.max1);//次大值為前半部分次大值與后半部分最大值的最大值 } else { mm.max1=m2.max1;//更新最大值為后半部分最大值 mm.max2=Math.max(m2.max2, m1.max1);//次大值為后半部分次大值與前半部分最大值的最大值 } } return mm;//返回 } }
注意:每次調用solve方法時,都要初始化mm,因為這樣才能使low和high更新時,mm中每次存放的為low~high的最大值和次大值;
空吧哇~