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)

发布了136 篇原创文章 · 获赞 112 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/heda3/article/details/104072844