LeetCode 算法 | 如何排列硬币?

阅读文本大概需要 4 分钟。

我给大家分享 LeetCode 算法题,主要都是挑选那些很可能在面试中出现的题,或者可能出现类似的题,多看看这些题至少能够在面试中不那么被动。

今天给大家分享的 LeetCode 算法题和硬币相关:如何排列硬币,一起来看一看。

题目

你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。给定一个数字 n,找出可形成完整阶梯行的总行数。n 是一个非负整数,并且在32位有符号整型的范围。

示例1

n = 5

硬币可排列成以下几行:
¤
¤ ¤
¤ ¤

因为第三行不完整,所以返回2.

示例2

n = 8

硬币可排列成以下几行:
¤
¤ ¤
¤ ¤ ¤
¤ ¤

因为第四行不完整,所以返回3.

题目结合示例,很好理解。这里主要给大家分享三个解题方法。

1. 直接干

为什么说直接干呢?拿到这个题,第一反应是,我从第一行开始往上加,等加到 n 的时候就结束,或者大于 n 的时候就结束即可。

这个思路没有问题,但是需要考虑一个小坑在里面,那就是数据溢出的问题,因为从 1 往上加的话,有可能最后一行加了之后,就超出整数范围了,就会变成负数,所以需要注意一下溢出问题。下面给出我的代码:

public int arrangeCoins(int n) {
    int layer = 1;
    int layerTmpt = 1;
    int result = 1;
    while(result < n) {
        layerTmpt++;
        // 说明溢出
        if (layerTmpt < 0) {
            return layer;
        }
        result += layerTmpt;
        // 说明溢出
        if (result < 0) {
            return layer;
        }
        layer++;
    }

    if(result == n) {
        return layer;
    } else {
        return layer - 1;
    }
}

2. 逆向思维

从刚刚我们分析中可知,如果从 1 开始往上加,会有可能造成数据溢出,那么我们可以反过来考虑,如果我们用 n 从 1 开始减呢?是不是就不存在溢出问题了?答案是肯定的。

public int arrangeCoins(int n) {
    int layer = 0;
    for (int i = 1; i <= n; ++i) {
        n -= i;
        if (n < 0) {
            return layer;
        } else {
            layer++;
        }
    }
    return layer;
}

这样的话,代码明显就简洁多了。如果面试官看到这种代码,肯定会更加满意。

3. 用数学公式

这种就没啥好说的了,根据题目意思,排列的硬币符合等差数列,1+2+3+...+x <= n,假设相等,先求出解,然后向下取整即可。

public int arrangeCoins(int n) {
    return (int) (Math.sqrt((long) n * 2 + 0.25) - 0.5);
}

这就很魔性了,一行代码写完了,不过这是基于数学公式来做的。

OK,这道算法题,就分享这么多,希望能对大家有所启发。我建了个 LeetCode 算法交流群,大家在下方可以加我微信,我拉你进群,共同学习交流。

END

关注我,你不会失望的!!

640?wx_fmt=jpeg


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值