LeetCode 441. 排列硬幣 --數組--二分法 --簡單

題目描述:

你總共有 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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章