LeetCode-441-排列硬币

排列硬币

题目描述:你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。

给定一个数字 n,找出可形成完整阶梯行的总行数。

n 是一个非负整数,并且在32位有符号整型的范围内。

示例说明请见LeetCode官网。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/arranging-coins/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一:穷举法

简单的累加,直到大于n为止,最后返回相应的层数。这种方法效率太低,n很大时会超时。

解法二:二分查找法

首先,上下限low和high分别是最大和最小的层数,最大值根据 n = x * (x + 1) / 2 估算得到,然后利用二分查找法找到最多可以放到第几层,最后返回层数即可。

public class LeetCode_441 {
    /**
     * 穷举法,n超大时会超时,效率不高
     *
     * @param n
     * @return
     */
    public static int arrangeCoins(int n) {
        int sum = 0, rows = 0;
        for (int i = 1; ; i++) {
            if (sum + i > n) {
                break;
            }
            sum += i;
            rows++;
        }
        return rows;
    }

    /**
     * 二分查找法
     *
     * @param n
     * @return
     */
    public static int arrangeCoins2(int n) {
        // low和high分别是最大和最小的层数,最大值根据 `n = x * (x + 1) / 2` 估算得到
        int low = 1, high = (int) Math.sqrt(Double.valueOf(Integer.MAX_VALUE) * 2), mid = -1;
        // 利用二分查找法找到最多可以放到第几层
        while (low <= high) {
            mid = (low + high) / 2;
            double temp = (double) mid * (mid + 1) / 2;
            if (temp > n) {
                high = mid - 1;
            } else if (temp < n) {
                low = mid + 1;
            } else {
                return mid;
            }
        }
        double temp = (double) mid * (mid + 1) / 2;
        if (temp > n) {
            return mid - 1;
        } else {
            return mid;
        }
    }

    public static void main(String[] args) {
        // 测试用例一,期望输出: 2
        System.out.println(arrangeCoins2(5));
        // 测试用例二,期望输出: 3
        System.out.println(arrangeCoins2(8));
        // 测试用例三,期望输出:65535
        System.out.println(arrangeCoins2(2147483647));
        // 测试用例三,期望输出:60070
        System.out.println(arrangeCoins2(1804289383));
    }
}

【每日寄语】 凡事若等明天做,机遇便从眼前过。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醉舞经阁-半卷书

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值