题目描述:
你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内。
示例 1:
n = 5
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤因为第三行不完整,所以返回2.
示例 2:n = 8
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤ ¤
¤ ¤因为第四行不完整,所以返回3.
参考链接:https://leetcode-cn.com/problems/arranging-coins
解题思路:
1、二分法
分析题意可知
(1+x)*x/2=n 其中的x为我们需要找的数
如何采用二分法,题目给出n,找x如何用二分,那么边界在哪里
边界一开始认为是n*n结果出错,x要找的数在n内即可
//Java
class Solution {
public int arrangeCoins(int n)
{
long left = 0;
long right =n;//原因n*n边界出错 修改为n
//排除上述特殊情况后,依据题目可以确定目标值一定在在左右边界之中
while (left < right)
{
long mid = left + (right-left+1) / 2;//+1取右中位数
long temp=(1+mid)*(mid)/2;
if (temp>n) //依据题目排除中位数(此判断中位数大于目标值,而题目要找的是小于或等于目标值的第一个元素) //
{
// nums[mid] 的值可以舍弃
right = mid - 1;
}
else //中位数小于于或等于目标值
{
// nums[mid] 不能舍弃
left = mid;//left=mid则要取右中位数
}
}
//循环结束只剩下最后一个值
return (int)left;
}
}
算法复杂度分析:
时间复杂度:O(nlogn)
空间复杂度:O(1)
2、数学计算
求方程的根
k(k+1) /2 = n得到
1/2k^2+1/2k-n=0
k={-1/2+sqrt(1/4+2n)}/2
做了如下变换:
//Java
class Solution
{
public int arrangeCoins(int n)
{
return (int)(Math.sqrt(2) * Math.sqrt(n + 0.125) - 0.5);
}
}
算法复杂度
时间复杂度:O(logn); 平方根的计算时间开销logn
空间复杂度:O(1)