Input: coins =[3,6,9], k =3Output: 9Explanation: The given coins can make the following amounts:Coin 3 produces multiples of 3:3,6,9,12,15, etc.Coin 6 produces multiples of 6:6,12,18,24, etc.Coin 9 produces multiples of 9:9,18,27,36, etc.All of the coins combined produce:3,6, _**9**_ ,12,15, etc.
Input: coins =[5,2], k =7Output: 12Explanation: The given coins can make the following amounts:Coin 5 produces multiples of 5:5,10,15,20, etc.Coin 2 produces multiples of 2:2,4,6,8,10,12, etc.All of the coins combined produce:2,4,5,6,8,10, _**12**_ ,14,15, etc.
Since we can only use one denomination at a time, the possible amounts are all positive multiples of each coin. The set of all such amounts is the union of all sequences {coin, 2coin, 3coin, …}. To find the k-th smallest, we can use binary search on the answer and count how many such numbers are ≤ x.
classSolution {
public:longlong kthSmallestAmount(vector<int>& coins, int k) {
longlong l =1, r =1e18, ans =-1;
while (l <= r) {
longlong m = l + (r - l) /2, cnt =0;
for (int c : coins) cnt += m / c;
if (cnt >= k) { ans = m; r = m -1; }
else l = m +1;
}
return ans;
}
};
1
2
3
4
5
6
7
8
9
10
11
funckthSmallestAmount(coins []int, kint) int64 {
l, r:= int64(1), int64(1e18)
varansint64 = -1forl<=r {
m:=l+ (r-l)/2cnt:= int64(0)
for_, c:=rangecoins { cnt+=m/ int64(c) }
ifcnt>= int64(k) { ans = m; r = m-1 } else { l = m+1 }
}
returnans}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution {
publiclongkthSmallestAmount(int[] coins, int k) {
long l = 1, r = (long)1e18, ans =-1;
while (l <= r) {
long m = l + (r - l) / 2, cnt = 0;
for (int c : coins) cnt += m / c;
if (cnt >= k) { ans = m; r = m - 1; }
else l = m + 1;
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
classSolution {
funkthSmallestAmount(coins: IntArray, k: Int): Long {
var l = 1Lvar r = 1e18.toLong()
var ans = -1Lwhile (l <= r) {
val m = l + (r - l) / 2var cnt = 0Lfor (c in coins) cnt += m / c
if (cnt >= k) { ans = m; r = m - 1 } else { l = m + 1 }
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defkthSmallestAmount(self, coins: list[int], k: int) -> int:
l, r, ans =1, 10**18, -1while l <= r:
m = (l + r) //2 cnt = sum(m // c for c in coins)
if cnt >= k:
ans = m
r = m -1else:
l = m +1return ans
1
2
3
4
5
6
7
8
9
10
11
12
impl Solution {
pubfnkth_smallest_amount(coins: Vec<i32>, k: i32) -> i64 {
let (mut l, mut r, mut ans) = (1i64, 1e18asi64, -1i64);
while l <= r {
let m = l + (r - l) /2;
letmut cnt =0i64;
for&c in&coins { cnt += m / c asi64; }
if cnt >= k asi64 { ans = m; r = m -1; } else { l = m +1; }
}
ans
}
}