力扣题解:441. 排列硬币

109 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

一、题目描述:

441. 排列硬币 - 力扣(LeetCode)

你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。

给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。

 

示例 1:

image.png

输入:n = 5
输出:2
解释:因为第三行不完整,所以返回 2 。

示例 2:

image.png

输入:n = 8
输出:3
解释:因为第四行不完整,所以返回 3 。

提示:

  • 1 <= n <= 2^31 - 1

二、思路分析:

简单的一元二次方程 假设 最后结果为 k 行

那么 k 行 有 k * (k + 1)/2 个

得到 k * (k + 1)/2 小于等于 n

解 一元二次 方程 k * (k + 1)/2 = n

最后的结果 √(2n + 0.25) - 0.5 然后向下取整就得到了 能支持的最大行数

三、AC 代码:

class Solution {
    func arrangeCoins(_ n: Int) -> Int {        
        return Int(floor(sqrt(CGFloat(2 * n) + 0.25) - 0.5))
    }
}

四、总结:

还是数学强大啊

首先,硬币按照题意摆放可以形成一个等差数列,到第i层共需要i(i+1)/2个硬币;
然后,需要求得最大的i,同时i(i+1)/2<=n,也就是距离d=n-i(i+1)/2的距离最小,同时d>=0; 接着,d=n-i(i+1)/2可以看做是i的函数,还是一个开口向下的二次函数;
同时,还要d>=0,暂时抛开i是整数这一限定,根据二次函数求根公式可知 i=[-b±√(b^2-4ac)]/(2a) 使得d为0;
最后,因为i>=0 的限定,所以i一定是[-b+√(b^2-4ac)]/(2a)领域内的整数,此处应当向下取整(原因各位大佬自己想一想吧)

范文参考:

441. 排列硬币 笨办法 C语言实现 - 排列硬币 - 力扣(LeetCode)