LeetCode刷题之硬币组合

145 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


题目描述

你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。

给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。

示例1 :

输入:n = 5
输出:2
解释:因为第三行不完整,所以返回 2 。

示例2 :

输入:n = 8
输出:3
解释:因为第四行不完整,所以返回 3 。

思路1:数学公式

设当前阶梯数为x,硬币数为y,可得以下不等式:

x×(x+1)<=2y,(x+1)×(x+2)>2yx×(x+1)<=2y,(x+1)×(x+2)>2y

利用放缩解不等式得:

2y2<x<2y\sqrt{2y}-2<x<\sqrt{2y}

image-20211031214043305

public static int arrangeCoins(int n) {
	return (int)(Math.sqrt(2) * Math.sqrt(n + 0.125) - 0.5);
}

思路2:二分

import java.util.*;

class Solution {
    public int arrangeCoins(int n) {
        long end = n;
        if (n > Math.pow(2, 16)) {
            end = n / 2;
        }
        return (int) getPosition(n, 0, n );
    }

    public long getPosition(int n, long begin, long end) {
        // 最终二分终止条件
        if (end - begin == 1) {
            long endValue = (end + 1) * end / 2 - n;
            if (endValue == 0) {
                return end;
            }
            return begin;
        }
        // 二分过程,不断逼近最终区间
        long middle = (end - begin) / 2 + begin;
        long valueMiddle = (middle + 1) * middle / 2 - n;
        if (valueMiddle == 0) {
            return middle;
        }
        if (valueMiddle < 0) {
            begin = middle;
        }
        if (valueMiddle > 0) {
            end = middle;
        }
        return getPosition(n, begin, end);
    }
}