website/content.en/ChapterFour/1600~1699/1681.Minimum-Incompatibility.md
You are given an integer array nums and an integer k. You are asked to distribute this array into k subsets of equal size such that there are no two equal elements in the same subset.
A subset's incompatibility is the difference between the maximum and minimum elements in that array.
Return the minimum possible sum of incompatibilities of the k subsets after distributing the array optimally, or return -1 if it is not possible.
A subset is a group integers that appear in the array with no particular order.
Example 1:
Input: nums = [1,2,1,4], k = 2
Output: 4
Explanation: The optimal distribution of subsets is [1,2] and [1,4].
The incompatibility is (2-1) + (4-1) = 4.
Note that [1,1] and [2,4] would result in a smaller sum, but the first subset contains 2 equal elements.
Example 2:
Input: nums = [6,3,8,1,3,1,2,2], k = 4
Output: 6
Explanation: The optimal distribution of subsets is [1,2], [2,3], [6,8], and [1,3].
The incompatibility is (2-1) + (3-2) + (8-6) + (3-1) = 6.
Example 3:
Input: nums = [5,3,3,6,3,3], k = 3
Output: -1
Explanation: It is impossible to distribute nums into 3 subsets where no two elements are equal in the same subset.
Constraints:
1 <= k <= nums.length <= 16nums.length is divisible by k1 <= nums[i] <= nums.lengthGiven an integer array nums and an integer k. You need to divide this array into k subsets of the same size, such that there are no two equal elements in the same subset. The incompatibility of a subset is the difference between the maximum and minimum values in that subset.
Return the minimum value of the sum of the incompatibilities of each subset after dividing the array into k subsets. If it is impossible to divide it into k subsets, return -1. A subset is defined as a collection of some numbers in the array, with no requirement on the order of the numbers.
package leetcode
import (
"math"
"sort"
)
func minimumIncompatibility(nums []int, k int) int {
sort.Ints(nums)
eachSize, counts := len(nums)/k, make([]int, len(nums)+1)
for i := range nums {
counts[nums[i]]++
if counts[nums[i]] > k {
return -1
}
}
orders := []int{}
for i := range counts {
orders = append(orders, i)
}
sort.Ints(orders)
res := math.MaxInt32
generatePermutation1681(nums, counts, orders, 0, 0, eachSize, &res, []int{})
if res == math.MaxInt32 {
return -1
}
return res
}
func generatePermutation1681(nums, counts, order []int, index, sum, eachSize int, res *int, current []int) {
if len(current) > 0 && len(current)%eachSize == 0 {
sum += current[len(current)-1] - current[len(current)-eachSize]
index = 0
}
if sum >= *res {
return
}
if len(current) == len(nums) {
if sum < *res {
*res = sum
}
return
}
for i := index; i < len(counts); i++ {
if counts[order[i]] == 0 {
continue
}
counts[order[i]]--
current = append(current, order[i])
generatePermutation1681(nums, counts, order, i+1, sum, eachSize, res, current)
current = current[:len(current)-1]
counts[order[i]]++
// This is the key pruning
if index == 0 {
break
}
}
}