这道题用数学法我是真的没有想到。。。
你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数
来源:力扣(LeetCode)
题目链接
1 <= n <= 2^31 - 1
一开始我的蠢方法:
class Solution {
public:
int arrangeCoins(int n) {
if(n < 3)
return 1;
if(n == 3)
return 2;
long long a = n;
for(long long i = 2;i <= a/2;i++)
{
if(i*(1+i) == 2*a)
return i;
else if(i*(1+i) < 2*a && 2*a < (i+1)*(i+2))
return i;
}
return -1;
}
};
运行时间12ms。。。太久了
考虑一下二分:
class Solution {
public:
int arrangeCoins(int n) {
if(n < 3)
return 1;
if( n == 3)
return 2;
int l = 2, r = n/2;
while(l <= r)
{
int mid = l + ((r-l)>>1);
if((long long)mid*(mid+1) == (long long)2*n)
return mid;
else if((long long)mid*(mid+1) < (long long)2*n)
l = mid + 1;
else
r = mid - 1;
}
return r;
}
};
说明一下为什么小于等于三时直接特判,因为可以将右边界从n变为n/2
最后这种方法,我看了题解才懂。。。
代码:
class Solution {
public:
int arrangeCoins(int n) {
return (int) ((sqrt((long long) 8 * n + 1) - 1) / 2);
}
};