Beginner Friendly | 🔍 Binary Search | 🔥 Optimized Solution | ⏳ O(n log m) | 💻 Java
🍬 Distributing Candies Optimally using Binary SearchImagine you have different piles of candies 🍭🍬 and k children 🧑‍🤝‍🧑. Each child should get equal candies fro
### **🍬 Distributing Candies Optimally using Binary Search**  

Imagine you have **different piles of candies** 🍭🍬 and **k children** 🧑‍🤝‍🧑. Each child should get **equal candies** from a **single pile**, and you can only **split piles** (not merge them). Our goal is to find **the maximum number of candies** each child can get.

---

## **💡 Intuition (Step-by-Step Understanding)**  

### **🔹 Step 1: Understanding the Problem**
1. Each pile has a certain number of candies 🍬.
2. We must **distribute candies fairly**, meaning each child should get the **same number** of candies.
3. We can **split piles into smaller ones**, but **not merge** them.
4. The objective is to **maximize the candies each child gets** while ensuring we can satisfy at least `k` children.

### **🔹 Step 2: Constraints and Observations**
- The **maximum number of candies a child can get** is limited by the **largest pile**.
- The **minimum** candies each child can get is `1`.
- If `k` is **larger than the total number of possible candy distributions**, return `0`.

### **🔹 Step 3: Using Binary Search for Efficiency**  
Instead of checking every possible amount of candies (`1` to `max(candies)`) one by one (**brute force**), we use **binary search** to quickly find the largest possible valid value.

---

## **🚀 Approach (Step-by-Step with Emojis)**
1️⃣ **Define the Range of Candies** 🎯  
   - The **minimum** candies per child = `1`.  
   - The **maximum** candies per child = `max(candies)`.  
   - We will **search in this range** using **binary search**.

2️⃣ **Binary Search to Find the Maximum Candies per Child** 🔍  
   - Pick a **mid value** = `(left + right) / 2` (possible candies per child).  
   - Check **how many children we can satisfy** by dividing each pile by `mid`.  
   - If we can **satisfy at least `k` children**, we **increase** `mid` (search for a larger number of candies per child).  
   - Otherwise, we **decrease** `mid` (search for a smaller number of candies per child).  

3️⃣ **Stopping Condition** ⛔  
   - The search stops when **left > right**.
   - The **highest valid `mid`** found is the answer.

---

## **🔢 Example Walkthrough**  
### **Example 1**
```plaintext
Input: candies = [5, 8, 6], k = 3
```

### **Step-by-Step Execution**  
#### **1️⃣ Initial Range**  
- **Left** = `1`, **Right** = `8` (max of array)  

#### **2️⃣ Binary Search Steps**  
| Left | Right | Mid (Candies per Child) | Children We Can Satisfy | Action |
|------|------|-------------------|----------------------|--------|
| 1    | 8    | 4                 | `(5/4) + (8/4) + (6/4) = 1 + 2 + 1 = 4` ✅ | Increase `mid` (`left = 5`) |
| 5    | 8    | 6                 | `(5/6) + (8/6) + (6/6) = 0 + 1 + 1 = 2` ❌ | Decrease `mid` (`right = 5`) |
| 5    | 5    | 5                 | `(5/5) + (8/5) + (6/5) = 1 + 1 + 1 = 3` ✅ | Increase `mid` (`left = 6`) |

#### **3️⃣ Final Answer**  
```plaintext
Output: 5 (Max candies per child)
```
Each child gets **5 candies**, which is the maximum possible.

---


## **⏳ Time Complexity Analysis**
| **Operation**        | **Time Complexity** | **Explanation** |
|----------------------|--------------------|-----------------|
| **Binary Search** 🔍 | `O(log m)`         | Searching in the range `[1, max(candies)]`. |
| **Checking Feasibility** 🏗️ | `O(n)`             | Looping through `candies` to count children. |
| **Total Complexity** ⏳ | `O(n log m)`      | Much better than brute force `O(n * max(candies))`. |

---

## **🔥 Why is Binary Search Better?**
**Brute Force** (Checking all `candiesPerChild` values) ⏳  
- Tries every value from `1` to `max(candies)`.  
- **Worst Case Complexity**: `O(n * max(candies))` (Too slow 😵).  

**Binary Search** (Efficiently finding the best value) 🚀  
- Eliminates **half** of the search space each time.  
- **Complexity**: `O(n log m)` (Fast ✅).  

---

## **💻 Optimized Java Code**
```java
class Solution {
    public int maximumCandies(int[] candies, long k) {
        if (k == 0) return 0; // Edge case: No children
        
        int left = 1, right = 0;
        for (int candy : candies) {
            right = Math.max(right, candy); // Get max candy in a pile
        }

        int result = 0;
        while (left <= right) {
            int mid = left + (right - left) / 2;

            // Count children we can satisfy
            long childrenCount = 0;
            for (int candy : candies) {
                childrenCount += candy / mid;
            }

            if (childrenCount >= k) { // We can distribute at least k children
                result = mid;
                left = mid + 1; // Try for a larger candy per child
            } else {
                right = mid - 1; // Try for a smaller value
            }
        }
        return result;
    }
}
```

---

![upvote.jpg](https://assets.leetcode.com/users/images/c0054da7-916c-4e98-83c8-a252082f53c9_1741916552.4457462.jpeg)

['Array', 'Two Pointers', 'Binary Search', 'Java']