排列硬币

你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。

给定一个数字 n,找出可形成完整阶梯行的总行数。

n 是一个非负整数,并且在32位有符号整型的范围内。

示例 1:

n = 5

硬币可排列成以下几行:
¤
¤ ¤
¤ ¤

因为第三行不完整,所以返回2.
示例 2:

n = 8

硬币可排列成以下几行:
¤
¤ ¤
¤ ¤ ¤
¤ ¤

因为第四行不完整,所以返回3.

二分法:

行数和硬 币数有如下对应关系:
[0, 1, 2, 3, 4,......,n]
[0, 1, 3, 6, 10,.....{(n + 1) × n}/2]

我们知道n枚硬 币排列的行数不可能超过n行。
所以我们从行数入手,查找硬 币数。
算法设计:
初始化:low = 0, high = n
当low≤high循环执行:
mid = (low + high) / 2
cost = (mid + 1) × mid / 2
当cost == n时,说明找到了,执行return \space midreturn mid.
当cost < n时,即排mid行用的硬 币数没超过n枚,可能还能多排几行,执行low = mid + 1
当cost > n时,即排mid行用的硬 币数已经超过n枚,应该减少行数,执行high = mid - 1
结束:返回highhigh(为什么不是lowlow,可以自行举例验证,比如n=8执行以上算法)

class Solution {
    public int arrangeCoins(int n) {
        long low = 1,high = n;
        long middle, sum;
        while(low <= high){
            middle = low + (high - low) / 2;
            sum = middle * (middle + 1) / 2;
            if(sum == n){
                return (int)middle;
            }else if(sum < n){
               low =  middle + 1;
            }else{
                high =  middle - 1;
            }
        }
        return (int)high;
    }
}    

 

posted @ 2021-03-05 20:25  王余阳  阅读(317)  评论(0)    收藏  举报