分治算法

分治算法的基本思想是将一个规模为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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值