leetcode 441.排列硬币
题目描述
你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内。
示例 1:
n = 5
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤
因为第三行不完整,所以返回2.
示例 2:
n = 8
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤ ¤
¤ ¤
因为第四行不完整,所以返回3.
解题思路
方法一: 迭代法,直接看代码吧,很简单
class Solution {
public:
int arrangeCoins(int n) {
if(n<0){
return -1;
}
int k = 1;
while(n-k >= 0){
n -= k;
k++;
}
return k-1;
}
};
方法二: 数学方法
可以推到一下数学公式
x
×
(
x
+
1
)
2
=
n
(
2
x
+
1
)
2
=
8
×
n
+
1
n
=
8
×
n
−
1
2
\begin{array}{l} \frac{{x \times (x + 1)}}{2} = n\\ {(2x + 1)^2} = 8 \times n + 1\\ n = \frac{{\sqrt {8 \times n} - 1}}{2} \end{array}
2x×(x+1)=n(2x+1)2=8×n+1n=28×n−1
所以代码如下:
class Solution {
public:
int arrangeCoins(int n) {
return n<0? -1:(sqrt(8*(long)n+1)-1)/2;
}
};
方法三: 二分法,使用二分法来缩小空间的访问
class Solution {
public:
int arrangeCoins(int n) {
long l = 0, r = n;
long mid = l + (r-l)/2;
while(l<r){
if(mid*(mid+1) == (long)2*n){
return mid;
}
else if(mid*(mid+1) < (long)2*n){
l = mid+1;
}
else{
r = mid;
}
mid = l + (r-l)/2;
}
return (l*(l+1)) == ((long)2*n) ? l: l-1;
}
};
欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步