Celebration Party
Problem
Let's consider the following situation. You've invited a lot of children to a celebration party, and you want to entertain them and also teach them something in the process. You are going to hire a few teachers and divide the children into groups and assign a teacher to each of the groups. This teacher will work with this group through the whole party.
But you know that for a teacher to work with a group of children efficiently children of that group should be of relatively the same age. More specifically age of any two children in the same group should differ by at most, one year.
Also, you want to minimize the number of groups. Because you want to hire fewer teachers, and spend the money on presents and other kinds of entertainment for the children. So, you need to divide children into the minimum possible number of groups. Such that the age of any two children in any group differs by at most one year.
Examples
Example 1
Input: ages = [2.5, 3.2, 3.5, 4.0, 4.8, 5.2, 6.0]
Output: 3
Explanation:
- Group 1: [2.5, 3.2, 3.5]
- Group 2: [4.0, 4.8, 5.2]
- Group 3: [6.0]
Minimum number of groups = 3
Example 2
Input: [1.1, 2.1, 3.3, 3.9, 5.0, 6.5]
Output: 4
Explanation:
- Group 1: [1.1, 2.1]
- Group 2: [3.3, 3.9]
- Group 3: [5.0]
- Group 4: [6.5]
Minimum number of groups = 4
Solution
Method 1 - Greedy
Reasoning
- Sorting ensures we consider ages in increasing order, preventing unnecessary splitting.
- By tracking the maximum group range (
currentMax + 1.0), we minimise the number of groups required. - If an age exceeds the range of the current group, start a new group.
Approach
- Sort the Input: Sorting ensures that we attempt to group consecutive elements together.
- Maintain a Group's Upper Bound: Use a variable to track the maximum allowable age for the current group. If the next age exceeds this, start a new group.
- Increment Group Counter: Every time a new group is started, increment the group counter.
Code
C++
class Solution {
public:
int minGroups(vector<double>& ages) {
sort(ages.begin(), ages.end()); // Step 1: Sort ages
int groups = 1; // Start with 1 group
double currentMax = ages[0]; // First group's maximum age
for (double age : ages) {
if (age > currentMax + 1.0) { // Step 2: Check if new group needed
groups++;
currentMax = age; // Start new group with this age
}
}
return groups;
}
};
int main() {
Solution solution;
vector<double> ages = {2.5, 3.2, 3.5, 4.0, 4.8, 5.2, 6.0};
cout << solution.minGroups(ages) << endl; // Output: 3
return 0;
}
Go
func minGroups(ages []float64) int {
sort.Float64s(ages) // Step 1: Sort ages
groups := 1
currentMax := ages[0] // First group's maximum age
for _, age := range ages {
if age > currentMax+1.0 { // Step 2: Check if new group needed
groups++
currentMax = age
}
}
return groups
}
func main() {
ages := []float64{2.5, 3.2, 3.5, 4.0, 4.8, 5.2, 6.0}
fmt.Println(minGroups(ages)) // Output: 3
}
Java
class Solution {
public int minGroups(double[] ages) {
Arrays.sort(ages); // Step 1: Sort ages
int groups = 1;
double currentMax = ages[0]; // First group's maximum age
for (double age : ages) {
if (age > currentMax + 1.0) { // Step 2: Check if new group needed
groups++;
currentMax = age;
}
}
return groups;
}
public static void main(String[] args) {
Solution solution = new Solution();
double[] ages = {2.5, 3.2, 3.5, 4.0, 4.8, 5.2, 6.0};
System.out.println(solution.minGroups(ages)); // Output: 3
}
}
Kotlin
class Solution {
fun minGroups(ages: DoubleArray): Int {
ages.sort() // Step 1: Sort ages
var groups = 1
var currentMax = ages[0] // First group's maximum age
for (age in ages) {
if (age > currentMax + 1.0) { // Step 2: Check if new group needed
groups++
currentMax = age
}
}
return groups
}
}
fun main() {
val solution = Solution()
val ages = doubleArrayOf(2.5, 3.2, 3.5, 4.0, 4.8, 5.2, 6.0)
println(solution.minGroups(ages)) // Output: 3
}
Python
class Solution:
def minGroups(self, ages):
ages.sort() # Step 1: Sort ages
groups = 1
current_max = ages[0] # First group's maximum age
for age in ages:
if age > current_max + 1.0: # Step 2: Check if new group needed
groups += 1
current_max = age
return groups
# Example usage
solution = Solution()
ages = [2.5, 3.2, 3.5, 4.0, 4.8, 5.2, 6.0]
print(solution.minGroups(ages)) # Output: 3
Rust
fn min_groups(mut ages: Vec<f64>) -> i32 {
ages.sort_by(|a, b| a.partial_cmp(b).unwrap()); // Step 1: Sort ages
let mut groups = 1;
let mut current_max = ages[0]; // First group's maximum age
for &age in &ages {
if age > current_max + 1.0 { // Step 2: Check if new group needed
groups += 1;
current_max = age;
}
}
groups
}
fn main() {
let ages = vec![2.5, 3.2, 3.5, 4.0, 4.8, 5.2, 6.0];
println!("{}", min_groups(ages)); // Output: 3
}
Complexity
- ⏰ Time complexity:
O(n log n)- Sorting:
O(n * log(n)) - Iteration:
O(n) - Total complexity:
O(n * log(n)).
- Sorting:
- 🧺 Space complexity:
O(1)as sorting can be done in place