1.题目
你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内。
示例:
n = 5硬币可排列成以下几行:¤¤ ¤¤ ¤因为第三行不完整,所以返回2.n = 8硬币可排列成以下几行:¤¤ ¤¤ ¤ ¤¤ ¤因为第四行不完整,所以返回3.
2.思路
等差数列求和公式
%7D%7B2%7Dd%2Cn%5Cin%20N%5E*#card=math&code=S_n%3Dna_1%2B%5Cfrac%7Bn%28n-1%29%7D%7B2%7Dd%2Cn%5Cin%20N%5E%2A)
从第1行阶梯开始累加硬币,即1 + 2 + 3 + … + k <= n。k从1开始枚举,由等差数列求和公式可得%20%C3%97%20%5Cfrac%7Bk%7D%7B2%7D#card=math&code=sum%20%3D%20%281%20%2B%20k%29%20%C3%97%20%5Cfrac%7Bk%7D%7B2%7D),最后while循环结束是因为sum > n,所以要返回k - 1。
public int arrangeCoins(int n) {long k = 1, sum = 1;while (sum <= n) {k++;sum = (1 + k) * k / 2;}return (int) k - 1;}
还有一种二分查找的:
答案的范围是[0,n]的有序区间,所以可以使用二分查找。我们要在[0,n]中找到一个数k(代码中的mid),使得%20%C3%97%20%5Cfrac%7Bk%7D%7B2%7D#card=math&code=%281%20%2B%20k%29%20%C3%97%20%5Cfrac%7Bk%7D%7B2%7D)刚好小于等于n,如果大于n,就排除一半区间。
public int arrangeCoins(int n) {long left = 0, right = n;while (left < right) {long mid = left + (right - left + 1) / 2;long sum = (1 + mid) * mid / 2;// sum大于n一定不是解if (sum > n) {// 下一轮搜索区间是 [left, mid - 1]right = mid - 1;} else {// 下一轮搜索区间是 [mid, right]left = mid;}}return (int) left;}
作者:maczhen
链接:https://leetcode-cn.com/problems/arranging-coins/solution/441-pai-lie-ying-bi-javabao-li-er-fen-ch-sqnv/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
