java减治法实现

用减治法求解n枚硬币问题

    有n枚硬币,其中有一枚是假币,已知真币与假币重量不同,给你一架天平, 要求设计出一个高效的算法,来检测出这枚假币。

package task3_1;

public final class CoinUtil {
    private CoinUtil(){}
    //使用right来保存正确的硬币重量,只有在剩下最后两个硬币的时候用得到
    private static int right;
    public static int Find(int[] arr,int a, int b){
        //如果传入的下标相同,代表只剩一个数组
        if (a==b){
            return a;
        }
        //用结束下标减去开始下标加一获得传过来的数组长度
        int len= b-a+1;
        //把数组分成四份,计算前三份的长度
        int size=(len-len%3)/3;
        //如果传入的下标是相邻的两个数,则分成两份
        if (len==2){
            if (arr[a]==right){
                return a;
            }else return b;
        }
        //根据前三份数组对应的下标求数组的和
        int sum1,sum2,sum3;

        sum1=sum(arr,a,a+size-1);

        sum2=sum(arr,a+size,a+2*size-1);

        sum3=sum(arr,a+2*size,a+3*size-1);
        //第一份数组的和以其他两份的大小都不一样,代表假币就在里面
        if (sum1!=sum2&&sum1!=sum3){
            //第一份数组有假币,表示其他两份都是真币,就可以求得真币的重量,right=数组总重量/数组长度
            right=sum2/len;
            return Find(arr,a,a+size-1);
            //第二份数组的和以其他两份的大小都不一样,代表假币就在里面
        } else if (sum2!=sum1&&sum2!=sum3) {
            //第二份数组有假币,表示其他两份都是真币,就可以求得真币的重量,right=数组总重量/数组长度
            right=sum1/len;
            return Find(arr,a+size,a+2*size-1);
            //第三份数组的和以其他两份的大小都不一样,代表假币就在里面
        } else if (sum3!=sum1&&sum3!=sum2) {
            //第三份数组有假币,表示其他两份都是真币,就可以求得真币的重量,right=数组总重量/数组长度
            right=sum2/len;
            return Find(arr,a+2*size,a+3*size-1);
            //代表假币不在这三份数组里面而在没被划分进数组的那堆零散的部分里
        }else{
            //零散数组有假币,表示其他两份都是真币,就可以求得真币的重量,right=数组总重量/数组长度
            right=sum1/len;
            return Find(arr,a+3*size,a+len-1);
        }
    }
    //获取数组下标a,b之间的和(包含a,b)
    private static int sum(int[] arr,int a,int b){
        int sum=0;
        for (int i = a; i <= b; i++) {
            sum=sum+arr[i];
        }
        return sum;
    }
}

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值