For each spell, we need to count how many potions form a successful pair. A pair is successful when spell * potion >= success. The simplest approach is to check every spell against every potion and count the valid combinations.
result array res to store the count for each spell.s in spells:cnt = 0.p in potions:s * p >= success, increment cnt.cnt to res.res.Where and are the sizes of the arrays and respectively.
If we sort the potions array, all successful potions for a given spell will be contiguous at the end. For a spell s, we need the minimum potion strength p such that s * p >= success, which means p >= success / s. Binary search can efficiently find this threshold index, and all potions from that index onward form successful pairs.
potions array in ascending order.s in spells:idx where s * potions[idx] >= success.len(potions) - idx.result.result array.class Solution:
def successfulPairs(self, spells: List[int], potions: List[int], success: int) -> List[int]:
potions.sort()
res = []
for s in spells:
l, r = 0, len(potions) - 1
idx = len(potions)
while l <= r:
m = (l + r) // 2
if s * potions[m] >= success:
r = m - 1
idx = m
else:
l = m + 1
res.append(len(potions) - idx)
return resWhere and are the sizes of the arrays and respectively.
If we sort both arrays, we can use the two pointer technique. A weaker spell needs a stronger potion to succeed, and a stronger spell needs at least as weak a potion. By processing spells in ascending order and potions in descending order, we can reuse the potion pointer position. Once a potion works for a spell, it works for all stronger spells too.
spells array and sort both spells and potions.j starting at the end of sorted potions.j left while spell * potions[j] >= success.m - j - 1 in a map keyed by spell strength.result by looking up each original spell's count in the map.result.class Solution:
def successfulPairs(self, spells: List[int], potions: List[int], success: int) -> List[int]:
n, m = len(spells), len(potions)
S = spells[:]
count = defaultdict(int)
spells.sort()
potions.sort()
j = m - 1
for i in range(n):
while j >= 0 and spells[i] * potions[j] >= success:
j -= 1
count[spells[i]] = m - j - 1
res = [0] * n
for i in range(n):
res[i] = count[S[i]]
return resWhere and are the sizes of the arrays and respectively.
The previous approach uses extra space to map spell values to their counts. We can avoid this by sorting indices of spells rather than the spells themselves. This way, we can directly write results to the correct positions in the output array without needing a lookup map.
sIdx and sort it by corresponding spell strength.potions array.j at the end of potions and result array res.index i in sorted order:j left while spells[sIdx[i]] * potions[j] >= success.res[sIdx[i]] = m - j - 1.res.class Solution:
def successfulPairs(self, spells: List[int], potions: List[int], success: int) -> List[int]:
n, m = len(spells), len(potions)
sIdx = list(range(n))
sIdx.sort(key=lambda x: spells[x])
potions.sort()
j = m - 1
res = [0] * n
for i in range(n):
while j >= 0 and spells[sIdx[i]] * potions[j] >= success:
j -= 1
res[sIdx[i]] = m - j - 1
return resWhere and are the sizes of the arrays and respectively.
When multiplying spell * potion, the result can exceed the range of a 32-bit integer since both values can be up to 10^5, making the product up to 10^10. Always cast to long before multiplication or use a 64-bit integer type to avoid overflow and incorrect comparisons.
A common mistake is incorrectly calculating the count of successful pairs after binary search. The binary search finds the first index where the condition is satisfied, and the count should be len(potions) - idx. Errors occur when using <= vs < in the binary search condition or when the index represents the wrong boundary.
Binary search only works on sorted arrays. A frequent oversight is attempting to use binary search on the original unsorted potions array, which leads to incorrect results. The potions array must be sorted first, and for the two-pointer approach, both arrays need to be sorted while preserving the original spell order for the output.