持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情
一、题目描述:
你总共有
n枚硬币,并计划将它们按阶梯状排列。对于一个由k行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。
示例 1:
输入:n = 5
输出:2
解释:因为第三行不完整,所以返回 2 。
示例 2:
输入:n = 8
输出:3
解释:因为第四行不完整,所以返回 3 。
提示:
- 1 <= n <= 2^31 - 1
二、思路分析:
首先,二分思路是从中找到一个数,计算这个数与它前面所有数(台阶)的和,然后用n来减去这个和,如果大于等于0,说明答案还在这个数的右边,如果小于零,说明答案在左边。 我们可以想到这个梯形是首项为1公差也为1的等差数列,那么我们可以通过前n项和计算公式 S=n*(a1+an)/2来得到这个数(包含在内)之前的所有台阶数之和。
三、AC 代码:
class Solution {
public int arrangeCoins(int n) {
int l=1;
int r=n;
while(l<r){
int mid=l+(r-l)/2+1;
//等差公式的变形 n>=mid*(1+mid)/2
if ((double)n/mid>=(double) (1+mid)/2){
l=mid;
}else r=mid-1;
}
return l;
}
}
范文参考:
题目简单就是要注意越界,提前把n存储在long中是必要的 - 排列硬币 - 力扣(LeetCode)
【Shi-Scala】【双双超越100%,还有谁?】排列硬币 - 排列硬币 - 力扣(LeetCode)
时间击败100%用户,时间换空间,可以用这个算法。如果用二分法,前面的循环好理解,后面的看代码注释就行。 - 排列硬币 - 力扣(LeetCode)