🧪🧙‍♂️ Successful Pairs of Spells and Potions – Binary Search Brew! ⚡️
💡 IntuitionYou’re given two arrays:spells[i] = power of the i-th spellpotions[j] = strength of the j-th potion
You need to count how many potions can be paired
# 💡 Intuition
You’re given two arrays:

spells[i] = power of the i-th spell

potions[j] = strength of the j-th potion
You need to count how many potions can be paired with each spell such that:
spell[i] * potion[j] ≥ success

---


# 🚀 Approach – Sort & Binary Search Combo! 🧠
To efficiently count how many potions will succeed with a given spell, we: 
1️⃣ Sort the potions array
2️⃣ For each spell, use binary search to find the first potion that satisfies spell * potion ≥ success
3️⃣ All potions from that point to the end of the array are valid ✅

---


# 🧭 Steps
Sort the potions array (once).

For each spell:

Binary search to find the lowest index where `spell * potion ≥ success`

The count is `potions.length - index`

Store the result for each spell.

---


# ⏱ Time & Space Complexity
Time Complexity:
- Sorting potions: O(m log m)
- For each spell: O(log m) binary search
- Total: O(n log m) ✅

Space Complexity: O(1) extra space (excluding output array)

---


# Code
```java []
class Solution {
    public int[] successfulPairs(int[] spells, int[] potions, long success) {
        int n = spells.length, m = potions.length;
        Arrays.sort(potions);
        int[] pairs = new int[n];
        for(int i = 0; i<n; i++){
            int low = 0, high = m-1;
            while(low<=high){
                int mid = low+(high-low)/2;
                long num = (long)spells[i]*potions[mid];
                if(num>=success) high = mid-1;
                else low = mid+1;
            }
            pairs[i] = m - (high+1);
        }
        return pairs;
    }
}
```
```C++ []
class Solution {
public:
    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success) {
        sort(potions.begin(), potions.end());
        int m = potions.size();
        vector<int> res;

        for (int spell : spells) {
            int low = 0, high = m - 1;
            while (low <= high) {
                int mid = low + (high - low) / 2;
                long long product = (long long) spell * potions[mid];
                if (product >= success) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
            res.push_back(m - (high + 1));
        }

        return res;
    }
};

```
```python []
from bisect import bisect_left

class Solution:
    def successfulPairs(self, spells: List[int], potions: List[int], success: int) -> List[int]:
        potions.sort()
        m = len(potions)
        res = []

        for spell in spells:
            target = (success + spell - 1) // spell  # Ceiling division to avoid float
            idx = bisect_left(potions, target)
            res.append(m - idx)

        return res

```

---


# 🎯 Summary
Combining sorting and binary search is a game-changer when you need to count elements that satisfy a condition efficiently. A perfect blend of logic and optimization 🔥
# If this made it easier for you, don’t forget to UPVOTE ⬆️ and share with your network. Let's learn together! 🙌💬

['Array', 'Two Pointers', 'Binary Search', 'Sorting', 'Python', 'C++', 'Java']