func min(a, b int) int {
if a < b {
return a
}
return b
}
func numRescueBoats(people []int, limit int) int {
weights := make(map[int]int, 0)
weightSet := []int{}
for _, weight := range people {
if _, ok := weights[weight]; !ok {
weights[weight] = 1
weightSet = append(weightSet, weight)
} else {
weights[weight] += 1
}
}
numBoats := 0
for _, weight := range weightSet {
if weight >= limit {
numBoats += weights[weight]
delete(weights, weight)
continue
}
complimentWeight := limit - weight
for i := complimentWeight; i > 0; i-- {
if i == weight {
numBoats += weights[weight] / 2
weights[weight] = weights[weight] % 2
if weights[weight] == 0 {
break
} else {
continue
}
}
if _, ok := weights[i]; ok {
minCount := min(weights[i], weights[weight])
weights[i] -= minCount
weights[weight] -= minCount
numBoats += minCount
}
if weights[weight] == 0 {
break
}
}
if weights[weight] != 0 {
numBoats += weights[weight]
delete(weights, weight)
} else {
delete(weights, weight)
}
}
return numBoats
}
-
We first create a map called
weights
, which holds data in the formatweight: count
, where weight is the weight of a person and count is the count of people with that weight. -
Following this, we iterate through unique weights.
-
If the
weight
is above the givenlimit
, we will need 1 boat for each person of said weight. -
If the
weight
is lesser thanlimit
, we must find acomplimentWeight
such that the sum of these two weights are lesser thanlimit.
-
Upon finding a
complimentWeight
, we can sendx
pairs of people onx
boats. The numberx
is determined by the minimum number of people with weight =weight
orcomplimentWeight
. -
A key point to note is that
complimentWeight + weight
need not have to be equal tolimit
. The sum being lesser works too. Thus, we check for compliment weights in the range[1, complimentWeight]
. -
Finally, if a
weight
does not have a compliment, or has a higher count than any possible compliment, the remainder (or entire count if no compliment found), must be sent through single boats.