Binary Search | Java | Simple code with Explanation
IntuitionThe problem requires finding the minimum time needed to repair a given number of cars using multiple mechanics with different efficiencies (rank). Sinc

---

# Intuition
The problem requires finding the minimum time needed to repair a given number of cars using multiple mechanics with different efficiencies (rank). Since a mechanic with rank `r` takes `r * k^2` time to repair `k` cars, we need to determine the optimal time `T` in which all cars can be repaired.

The core observation is that if a given time `T` is feasible (i.e., we can repair all cars within `T`), then higher values of `T` are also feasible. This suggests a **binary search** approach.

---

# Approach
1. **Determine the search range**:
   - The minimum possible time is `1`.
   - The maximum possible time occurs when the slowest mechanic (highest rank) repairs all cars, leading to an upper bound of `max_rank * cars^2`.

2. **Binary search on the time `T`**:
   - Compute the mid-point `T = (low + high) / 2`.
   - Check if it's possible to repair all cars within `T` using a helper function `valid(T, ranks, cars)`.
   - If feasible, update the answer and try a smaller time (`high = mid - 1`).
   - Otherwise, increase the lower bound (`low = mid + 1`).

3. **Validation function (`valid`)**:
   - For each mechanic of rank `r`, determine how many cars they can repair within time `T` using `floor(sqrt(T / r))`.
   - Sum up the total repaired cars.
   - If the total is at least `cars`, return `true`; otherwise, return `false`.

---

# Complexity
- **Time complexity**:  
  - The binary search runs in **`O(log (max_rank * cars^2))`**.
  - For each mid-value, we check all mechanics, taking **O(n)** time.
  - Thus, the overall complexity is **`O(n log (max_rank * cars^2))`**.

- **Space complexity**:  
  - **O(1)**
---
# Code
```java []
class Solution {
    public long repairCars(int[] ranks, int cars) {
        int max=Integer.MIN_VALUE;
        for(int i=0;i<ranks.length;i++)
        {
            max=Math.max(max,ranks[i]);
        }
        long low=1,high=(long)max*cars*cars;
        long ans=0;
        while(low<=high)
        {
            long mid=(low+high)/2;
            if(valid(mid,ranks,cars))
            {
                ans=mid;
                high=mid-1;
            }
            else
            {
                low=mid+1;
            }
        }
        return ans;
    }
    public boolean valid(long mid,int ranks[],int cars)
    {
        long count=0;
        for(int i:ranks)
        {
            long c=mid/i;
            count+=(long)Math.sqrt(c);
        }
        if(count>=cars)
         return true;
        return false;

    }
}
```
['Java']