1681. 最小不兼容性Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
给你一个整数数组 nums 和一个整数 k 。你需要将这个数组划分到 k 个相同大小的子集中,使得同一个子集里面没有两个相同的元素。
一个子集的 不兼容性 是该子集里面最大值和最小值的差。
请你返回将数组分成 k 个子集后,各子集 不兼容性 的 和 的 最小值 ,如果无法分成分成 k 个子集,返回 -1 。
子集的定义是数组中一些数字的集合,对数字顺序没有要求。
示例 1:
输入:nums = [1,2,1,4], k = 2
输出:4
解释:最优的分配是 [1,2] 和 [1,4] 。
不兼容性和为 (2-1) + (4-1) = 4 。
注意到 [1,1] 和 [2,4] 可以得到更小的和,但是第一个集合有 2 个相同的元素,所以不可行。
示例 2:
输入:nums = [6,3,8,1,3,1,2,2], k = 4
输出:6
解释:最优的子集分配为 [1,2],[2,3],[6,8] 和 [1,3] 。
不兼容性和为 (2-1) + (3-2) + (8-6) + (3-1) = 6 。
示例 3:
输入:nums = [5,3,3,6,3,3], k = 3
输出:-1
解释:没办法将这些数字分配到 3 个子集且满足每个子集里没有相同数字。
提示:
- 1 <= k <= nums.length <= 16
- nums.length 能被 k 整除。
- 1 <= nums[i] <= nums.length
# 思路
dfs
# 解法
class Solution {
int result = Integer.MAX_VALUE;
public int minimumIncompatibility(int[] nums, int k) {
Arrays.sort(nums);
Bucket[] buckets = new Bucket[k];
for (int i = 0; i < k; ++i)
buckets[i] = new Bucket();
int bucketSize = nums.length / k;
dfs(nums, 0, 0, buckets, bucketSize);
return result == Integer.MAX_VALUE ? -1 : result;
}
private void dfs (int[] nums, int index, int sum, Bucket[] buckets, int bucketSize){
if (index == nums.length){
result = sum;
return;
}
int num = nums[index];
int currentSize = bucketSize;
for (Bucket bucket : buckets){
if (bucket.size == currentSize || bucket.max == num)
continue;
currentSize = bucket.size;
int prevMax = bucket.max;
bucket.max = num;
bucket.size++;
int delta = currentSize == 0? 0: bucket.max - prevMax;
if (sum + delta < result)
dfs(nums, index + 1, sum + delta, buckets, bucketSize);
bucket.size--;
bucket.max = prevMax;
}
}
class Bucket {
int size = 0;
int max = 0;
Bucket(){}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 总结
- 分析出几种情况,然后分别对各个情况实现


