Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
You are given a positive integer array grades which represents the grades of students in a university. You would like to enter all these students into a competition in ordered non-empty groups, such that the ordering meets the following conditions:
ith group is less than the sum of the grades of students in the (i + 1)th group, for all groups (except the last).ith group is less than the total number of students in the (i + 1)th group, for all groups (except the last).Return the maximum number of groups that can be formed.
Example 1:
Input: grades = [10,6,12,7,3,5] Output: 3 Explanation: The following is a possible way to form 3 groups of students: - 1st group has the students with grades = [12]. Sum of grades: 12. Student count: 1 - 2nd group has the students with grades = [6,7]. Sum of grades: 6 + 7 = 13. Student count: 2 - 3rd group has the students with grades = [10,3,5]. Sum of grades: 10 + 3 + 5 = 18. Student count: 3 It can be shown that it is not possible to form more than 3 groups.
Example 2:
Input: grades = [8,8] Output: 1 Explanation: We can only form 1 group, since forming 2 groups would lead to an equal number of students in both groups.
Constraints:
1 <= grades.length <= 1051 <= grades[i] <= 105Problem summary: You are given a positive integer array grades which represents the grades of students in a university. You would like to enter all these students into a competition in ordered non-empty groups, such that the ordering meets the following conditions: The sum of the grades of students in the ith group is less than the sum of the grades of students in the (i + 1)th group, for all groups (except the last). The total number of students in the ith group is less than the total number of students in the (i + 1)th group, for all groups (except the last). Return the maximum number of groups that can be formed.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Math · Binary Search · Greedy
[10,6,12,7,3,5]
[8,8]
maximum-height-by-stacking-cuboids)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2358: Maximum Number of Groups Entering a Competition
class Solution {
public int maximumGroups(int[] grades) {
int n = grades.length;
int l = 0, r = n;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (1L * mid * mid + mid > n * 2L) {
r = mid - 1;
} else {
l = mid;
}
}
return l;
}
}
// Accepted solution for LeetCode #2358: Maximum Number of Groups Entering a Competition
func maximumGroups(grades []int) int {
n := len(grades)
return sort.Search(n, func(k int) bool {
k++
return k*k+k > n*2
})
}
# Accepted solution for LeetCode #2358: Maximum Number of Groups Entering a Competition
class Solution:
def maximumGroups(self, grades: List[int]) -> int:
n = len(grades)
return bisect_right(range(n + 1), n * 2, key=lambda x: x * x + x) - 1
// Accepted solution for LeetCode #2358: Maximum Number of Groups Entering a Competition
impl Solution {
pub fn maximum_groups(grades: Vec<i32>) -> i32 {
let n = grades.len() as i64;
let (mut l, mut r) = (0i64, n);
while l < r {
let mid = (l + r + 1) / 2;
if mid * mid + mid > 2 * n {
r = mid - 1;
} else {
l = mid;
}
}
l as i32
}
}
// Accepted solution for LeetCode #2358: Maximum Number of Groups Entering a Competition
function maximumGroups(grades: number[]): number {
const n = grades.length;
let l = 1;
let r = n;
while (l < r) {
const mid = (l + r + 1) >> 1;
if (mid * mid + mid > n * 2) {
r = mid - 1;
} else {
l = mid;
}
}
return l;
}
Use this to step through a reusable interview workflow for this problem.
Check every element from left to right until we find the target or exhaust the array. Each comparison is O(1), and we may visit all n elements, giving O(n). No extra space needed.
Each comparison eliminates half the remaining search space. After k comparisons, the space is n/2ᵏ. We stop when the space is 1, so k = log₂ n. No extra memory needed — just two pointers (lo, hi).
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Wrong move: Setting `lo = mid` or `hi = mid` can stall and create an infinite loop.
Usually fails on: Two-element ranges never converge.
Fix: Use `lo = mid + 1` or `hi = mid - 1` where appropriate.
Wrong move: Locally optimal choices may fail globally.
Usually fails on: Counterexamples appear on crafted input orderings.
Fix: Verify with exchange argument or monotonic objective before committing.