Arranging Coins,LeetCode,441

LeetCode 441题 “Arranging Coins” 是一个中等难度的数学问题。题目描述如下:

你总共有 n 枚硬币,并希望将它们排列成一个阶梯形状,第 k 行必须正好有 k 枚硬币。

给你一个整数 n,返回你可以完整排列的行数。

示例 1:

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

示例 2:

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

解题思路

这个问题可以通过数学公式和二分查找来解决。

方法一:数学公式

我们知道,前 k 行需要的硬币总数是: [ S = \frac{k(k + 1)}{2} ]

我们需要找到一个最大的 k,使得: [ \frac{k(k + 1)}{2} \leq n ]

这可以通过解以下不等式得到: [ k^2 + k – 2n \leq 0 ]

使用求根公式: [ k = \frac{-b \pm \sqrt{b^2 – 4ac}}{2a} ] 其中,a = 1b = 1c = -2n

所以: [ k = \frac{-1 \pm \sqrt{1 + 8n}}{2} ]

我们取正根: [ k = \frac{-1 + \sqrt{1 + 8n}}{2} ]

最后取整即可。

方法二:二分查找

我们可以使用二分查找来找到最大的 k,使得: [ \frac{k(k + 1)}{2} \leq n ]

初始化 left = 1right = n,然后进行二分查找。

代码实现

方法一:数学公式

import math

def arrangeCoins(n: int) -> int: return int((-1 + math.sqrt(1 + 8 * n)) // 2)

示例

print(arrangeCoins(5)) # 输出: 2 print(arrangeCoins(8)) # 输出: 3

方法二:二分查找

def arrangeCoins(n: int) -> int: left, right = 1, n while left <= right: mid = (left + right) // 2 current = mid * (mid + 1) // 2 if current == n: return mid elif current < n: left = mid + 1 else: right = mid - 1 return right

示例

print(arrangeCoins(5)) # 输出: 2 print(arrangeCoins(8)) # 输出: 3

总结

  • 数学公式法:通过求解一元二次方程来直接计算结果,时间复杂度为 (O(1))。
  • 二分查找法:通过二分查找逐步逼近结果,时间复杂度为 (O(\log n))。

两种方法各有优劣,数学公式法更直观且速度快,但可能存在浮点数精度问题;二分查找法更通用且精度高,但稍微复杂一些。

希望这些详细的解释和代码示例能帮助你理解和解决这个题目!如果有更多问题,欢迎继续提问。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注