Don't search the array — search the answer range. Set lo = min possible, hi = max possible, binary search for the boundary where isFeasible(mid) flips from false to true (or vice versa).
isFeasible(mid) in O(n) or O(n log n)O(log k) binary search iterations on the answer range k. Each iteration calls isFeasible in O(n). Total: O(n log k). No auxiliary space beyond a few variables.
// ── Binary Search on Answer ────────────────────────────────────── int lo = minPossible, hi = maxPossible; int ans = hi; // default to largest (minimize) or smallest (maximize) while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (isFeasible(mid)) { ans = mid; // ✅ valid — try to do better (go smaller) hi = mid - 1; } else { lo = mid + 1; // ❌ not valid — need more capacity } } return ans; // isFeasible — Koko: can she eat all piles in h hours at speed k? boolean isFeasible(int k) { int hours = 0; for (int pile : piles) hours += (pile + k - 1) / k; // ⌈pile/k⌉ using integer math return hours <= h; }