美文网首页
P13-排列硬币-二分查找/牛顿迭代

P13-排列硬币-二分查找/牛顿迭代

作者: YonchanLew | 来源:发表于2021-05-12 23:12 被阅读0次
//排列硬币
/*
* 总共有n枚硬币,将他们摆成一个阶梯形状,第k行就必须正好有k枚硬币
* 给定一个数字n,找出可形成完整阶梯行的总行数。
* n是一个非负整数,并且在32位有符号整型的范围内
*
* 假如n=5,
* ○
* ○ ○
* ○ ○   所以结果是2,只有第一第二行是完整的,第三行不完整
* */
public class P13 {
    public static void main(String[] args) {
        System.out.println(arrangeCoins(100));
        System.out.println(arrangeCoins2(100));
        System.out.println(arrangeCoins3(100));
    }

    //1、暴力
    //准备放硬币之前,判断行号是否小于硬币数,是的话减行号,然后下一行
    public static int arrangeCoins(int num){
        //i从1开始,作为行号
        for(int i=1; i<=num; i++){
            num = num - i;
            if(num <= i){
                return i;
            }
        }
        return 0;
    }

    //2、二分查找
    //上面的方法需要把n放完才知道结果
    /*
    * num个硬币,先假设能放num行,如果num行的硬币总数是x,x肯定大于num
    * 3个硬币,假设放3行,即总数是6,6>3是必然的,答案必然在3行及以内,用二分查找
    * 10个硬币,假设放10行,即总数是55,55必然大于10,答案必然在10行及以内,用二分查找
    * */
    public static int arrangeCoins2(int num){
        int low = 0;
        int high = num;     //假设num个硬币放num行
        while(low <= high){
            int mid = (low+high) / 2;
            //x行硬币总数是等差数列公式
            int cost = (mid+1) * mid / 2;
            if(cost == num){
                return mid;     //找到行数
            }else if(cost > num){
                high = mid - 1;
            }else{
                low = mid + 1;
            }
        }
        return high;
    }

    //3、牛顿迭代
    public static int arrangeCoins3(int num){
        if(num == 0){
            return 0;
        }
        return (int)sqrt(num, num);
    }

    //公式本来是 (x + y/x) / 2,看回P8,
    //但因为等差数列公式是 (x+1)*x / 2 = n (n就是总数的意思,等差数列求和,即总硬币数,x是行号)
    //x平方 = 2n - x,就是要求2n-x的平方根,x = 根号(2n-x)
    //牛顿迭代本来就是依赖一个公式 x = y/x,看回P8啊,要求的是y的平方根,
    //现在要求2n-x的平方根,所以要将 2n-x 代入 y
    private static double sqrt(double x, int num) {
        double res = (x + (2*num-x)/x) / 2;
        if(res == x){
            return x;
        }else{
            return sqrt(res, num);
        }
    }
}

相关文章

  • P13-排列硬币-二分查找/牛顿迭代

  • 算法4 读书笔记

    1.二分查找的迭代实现 #pragma warning(disable:4996) #include /*二分查找...

  • c++ primer 阅读 day8

    3.4 迭代器介绍 使用迭代器运算二分查找 3.5 数组

  • 16 基本查找算法:二分查找算法

    二分查找算法 原理 二分查找算法也叫折半法查找法,要求待查找的列表必须是按关键字大小有序排列的顺序表。查找过程如下...

  • 双指针(链表、数组)

    二分查找用于有序的排列python中的二分查找模块bisect,Python中的list.inidex时间复杂度是...

  • 二分法模板

    【推荐:】二分查找的迭代Iterative写法(2)重点掌握 [ left, right ) 半开半闭区间迭代写法...

  • 二分查找及其扩展

    在有序数组中,二分查找是效率较高的查找算法。二分查找一般有递归和迭代 对有序数组查找指定数字在数组中出现的次数//...

  • PHP的常用算法

    1、冒泡排序 2、快速排序 3、二分查找 假设数组是升序排列。

  • 2018-08-13

    数据结构 二分查找 1、使用二分查找需要满足的条件: (1) 存储在数组中 (2) 有序排列 所以如果是用链表存储...

  • 前端面试之算法二分法

    使用二分法的前提是,目标数组的元素必须是有序排列的,所以二分法属于有序查找算法 二分法又称为“折半查找”,从数组的...

网友评论

      本文标题:P13-排列硬币-二分查找/牛顿迭代

      本文链接:https://www.haomeiwen.com/subject/vitbdltx.html