LeetCode 题解工作台
单面值组合的第 K 小金额
给你一个整数数组 coins 表示不同面额的硬币,另给你一个整数 k 。 你有无限量的每种面额的硬币。但是,你 不能 组合使用不同面额的硬币。 返回使用这些硬币能制造的 第 k th 小 金额。 示例 1: 输入: coins = [3,6,9], k = 3 输出: 9 解释: 给定的硬币可以制造…
6
题型
5
代码语言
3
相关题
当前训练重点
困难 · 二分·搜索·答案·空间
答案摘要
我们可以将题目转化为:找到最小的正整数 ,使得小于等于 的且满足条件的数的个数恰好为 个。如果 满足条件,那么对任意 $x' > x$ 的 也满足条件,这存在单调性,因此我们可以使用二分查找,找到最小的满足条件的 。 我们定义一个函数 `check(x)`,用来判断小于等于 的且满足条件的数的个数是否大于等于 。我们需要计算有多少个数可以由 中的数组合得到。
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路
题目描述
给你一个整数数组 coins 表示不同面额的硬币,另给你一个整数 k 。
你有无限量的每种面额的硬币。但是,你 不能 组合使用不同面额的硬币。
返回使用这些硬币能制造的 第 kth 小 金额。
示例 1:
输入: coins = [3,6,9], k = 3
输出: 9
解释:给定的硬币可以制造以下金额:
3元硬币产生3的倍数:3, 6, 9, 12, 15等。
6元硬币产生6的倍数:6, 12, 18, 24等。
9元硬币产生9的倍数:9, 18, 27, 36等。
所有硬币合起来可以产生:3, 6, 9, 12, 15等。
示例 2:
输入:coins = [5,2], k = 7
输出:12
解释:给定的硬币可以制造以下金额:
5元硬币产生5的倍数:5, 10, 15, 20等。
2元硬币产生2的倍数:2, 4, 6, 8, 10, 12等。
所有硬币合起来可以产生:2, 4, 5, 6, 8, 10, 12, 14, 15等。
提示:
1 <= coins.length <= 151 <= coins[i] <= 251 <= k <= 2 * 109coins包含两两不同的整数。
解题思路
方法一:二分查找 + 容斥原理
我们可以将题目转化为:找到最小的正整数 ,使得小于等于 的且满足条件的数的个数恰好为 个。如果 满足条件,那么对任意 的 也满足条件,这存在单调性,因此我们可以使用二分查找,找到最小的满足条件的 。
我们定义一个函数 check(x),用来判断小于等于 的且满足条件的数的个数是否大于等于 。我们需要计算有多少个数可以由 中的数组合得到。
假设 为 ,根据容斥原理,小于等于 的满足条件的数的个数为:
如果 为 ,小于等于 的满足条件的数的个数为:
可以看到,我们需要累加所有任意奇数个数的情况,减去所有任意偶数个数的情况。
由于 ,我们可以使用二进制枚举的方式,枚举所有的子集,计算满足条件的数的个数,我们记为 。如果 ,那么我们需要找到最小的 ,使得 为真。
在二分查找开始时,我们定义二分查找的左边界 ,右边界 ,然后我们不断地将中间值 代入 check 函数中,如果 check(mid) 为真,那么我们将右边界 更新为 ,否则我们将左边界 更新为 。最终返回 。
时间复杂度 ,其中 是数组 的长度,而 是数组 中的最大值。
class Solution:
def findKthSmallest(self, coins: List[int], k: int) -> int:
def check(mx: int) -> bool:
cnt = 0
for i in range(1, 1 << len(coins)):
v = 1
for j, x in enumerate(coins):
if i >> j & 1:
v = lcm(v, x)
if v > mx:
break
m = i.bit_count()
if m & 1:
cnt += mx // v
else:
cnt -= mx // v
return cnt >= k
return bisect_left(range(10**11), True, key=check)
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity is O(n log(k * maxCoin)) because each binary search step counts multiples for n coins. Space complexity is O(1) beyond input storage since no extra arrays are needed. |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Check whether you can count multiples without generating sequences explicitly.
- question_mark
They may hint at binary searching over possible sums rather than coin indices.
- question_mark
Expect questions about handling k up to 2 billion efficiently.
常见陷阱
外企场景- error
Mistakenly combining different coin denominations in a sum, violating the problem constraints.
- error
Generating all multiples up to k, causing memory overflow and slow execution.
- error
Failing to handle duplicate sums correctly when different coins produce the same amount.
进阶变体
外企场景- arrow_right_alt
Find kth largest amount instead of smallest using single-denomination multiples.
- arrow_right_alt
Allow combining at most two denominations per sum while maintaining a large k.
- arrow_right_alt
Restrict coin denominations to prime numbers only, testing counting efficiency.