持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
一、题目描述:
你总共有
n枚硬币,并计划将它们按阶梯状排列。对于一个由k行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。
示例 1:
输入:n = 5
输出:2
解释:因为第三行不完整,所以返回 2 。
示例 2:
输入:n = 8
输出:3
解释:因为第四行不完整,所以返回 3 。
提示:
- 1 <= n <= 2^31 - 1
二、思路分析:
x^2 + x = 2n; x = (2n - x) / x
这个方法得注意三点:
1、迭代的x不能为0,否则会返回nan,因为x会作为除数
2、牛顿迭代的结果返回的是一个近似值,该近似值在迭代的过程中不断接近真实值,但机会不可能完全等于真实值,所以它的迭代次数与你设置的精度有关,你如果直接用double类型的进度(小数点后17位),那样消耗的时间会非常长,所以最好自定义精度
3、如果第x排恰好需要n个硬币数或者十分接近,那么迭代的近似值就很有可能在一个整数的左右两次振荡,然而因为最后的答案是一个整形变量,浮点数转整形直接舍去小数部分,就可能导致最后结果错误
三、AC 代码:
class Solution {
public:
double sqrt(double x, double n) {
double ret = (x + (2 * n - x) / x) / 2;
if (ret > x ? (ret - x < 0.01) : (x - ret < 0.01)) {
return ret;
}
else {
return sqrt(ret, n);
}
}
int arrangeCoins(int n) {
if (!n) {
return 0;
}
double ret = sqrt(n, n);
long long ans = sqrt(n, n);
long long x = ans + 1;
if ((x + 1) * x / 2 == n) {
return ans + 1;
}
else {
return ans;
}
}
};