題目描述:
你總共有 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)