分治算法

来源:互联网 发布:淘宝直播时怎么调镜像 编辑:程序博客网 时间:2024/06/03 14:39

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。
分治法解题的一般步骤:
(1)分解,将要解决的问题划分成若干规模较小的同类问题;
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
1.求解一组数组元素的最大值和最小值

public class FenZ {    public static void main(String[] args) {        int array[] = { -2, 9, 1, -4, 6 };        int[] Max = new int[1]; // java对于实参传递,是采用值传递,所以要改成数组,不能直接使用变量去计算最大值和最小值。        int[] Min = new int[1];        max_min(array, 0, array.length - 1, Max, Min);        System.out.println("最大值: " + Max[0]);        System.out.println("最小值: " + Min[0]);    }    public static void max_min(int[] a, int left, int right, int[] maxnum, int[] minnum) {        if (left == right) // 当只有一个元素时候,直接得出最大值和最小值        {            maxnum[0] = a[left];            minnum[0] = a[right];        } else if (left + 1 == right)// 当数组中有两个元素时,直接判断哪个元素大,哪个元素小        {            if (a[left] > a[right]) {                maxnum[0] = a[left];                minnum[0] = a[right];            } else {                maxnum[0] = a[right];                minnum[0] = a[left];            }        } else {            int m = (left + right) / 2;            int lmax[] = { 0 };            int lmin[] = { 0 };            int rmax[] = { 0 };            int rmin[] = { 0 };            max_min(a, left, m, lmax, lmin);            max_min(a, m + 1, right, rmax, rmin);            if (lmax[0] > rmax[0]) {                maxnum[0] = lmax[0];            } else {                maxnum[0] = rmax[0];            }            if (lmin[0] < rmin[0]) {                minnum[0] = lmin[0];            } else {                minnum[0] = rmin[0];            }        }    }}

2.寻找假币

public class FenZ {    public static void main(String[] args) {        int arr[]={2,2,2,2,2,1,2,2,2,2,2,2,2,};        int x=method(arr,0,arr.length-1);        if(x==-1){            System.out.println("没有假币");        }else{            System.out.println("第"+(x+1)+"个金币是假币!");        }    }    private static int method(int[] arr, int l, int r) {        int re,sum1=0,sum2=0,mid;        if(l==r){               //删选到最后一个币时还存在假币            if(arr[l]==2){                return -1;            }else{                return l;            }        }        //只有两个金币时        if(l+1==r){            if(arr[l]<arr[r]){                re=l;                return re;            }else if(arr[l]>arr[r]){                re=r;                return re;            }else{                return -1;            }        }        //金币数是偶数        if((r-l+1)%2==0){            for(int i=l;i<=l+(r-l)/2;i++){      //前半段 求和                sum1=sum1+arr[i];            }            for(int i=l+(r-l)/2+1;i<=r;i++){    //后半段 求和                sum2=sum2+arr[i];            }            if(sum1>sum2){                re=method(arr,l+(r-l)/2+1,r);                return re;            }else if(sum1<sum2){                re=method(arr,l,l+(r-l)/2);                return re;            }else{                return re=-1;//sum1=sum2没有假币,返回负数            }        }        //金币数是奇数时        else{            for(int i=l;i<=l+(r-l)/2-1;i++){        //前半段 求和                sum1=sum1+arr[i];            }            for(int i=l+(r-l)/2+1;i<=r;i++){        //后半段 求和                sum2=sum2+arr[i];            }            mid=l+(r-l)/2;            if(sum1>sum2){                re=method(arr,l+(r-l)/2+1,r);                return re;            }else if(sum1<sum2){                re=method(arr,l,l+(r-l)/2-1);                return re;            }else{                if(arr[mid]==arr[l]){                    return -1;//没有假币                }else{                    return mid;                }            }        }    }}
第9个金币是假币!
0 0