有 n 位用户参加活动,他们的 ID 从 0 到 n - 1,每位用户都 恰好 属于某一用户组。给你一个长度为 n 的数组 groupSizes,其中包含每位用户所处的用户组的大小,请你返回用户分组情况(存在的用户组以及每个组中用户的 ID)。
你可以任何顺序返回解决方案,ID 的顺序也不受限制。此外,题目给出的数据保证至少存在一种解决方案。
``
示例 1:
输入:groupSizes = [3,3,3,3,3,1,3]
输出:[[5],[0,1,2],[3,4,6]]
解释:
其他可能的解决方案有 [[2,1,6],[5],[0,4,3]] 和 [[5],[0,6,2],[4,3,1]]。
示例 2:
输入:groupSizes = [2,1,3,3,3,2]
输出:[[1],[0,5],[2,3,4]]
提示:
groupSizes.length == n
1 <= n <= 500
1 <= groupSizes[i] <= n
这个题目是用来练习贪心算法的,也顺带熟悉了一下基本的数据结构
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关
遍历整个数组,从第一个开始就分组,一边遍历一边分组(这是基本思想)
首先用一个哈希表来存储groupSizes[i](也就是当前值所在组存在的元素个数)和当前值所在的组(用一个list来存储)(这是要用到的数据结构)
从第一个数开始,如果map中不包含groupSizes[i],就创建一个新list,将groupSizes[i]和这个list存储到map中,然后再讲当前值添加到这个list中,在判断这个list是不是满了(list.size == groupSizes[i]),如果相等,就把这个list添加到要返回的list中(注意添加的list应该是副本,不然会被清空),再将list清空(这是遍历过程要做的操作)
遍历完整个数组,返回结果
class Solution {
public List<List<Integer>> groupThePeople(int[] groupSizes) {
//用一个hashmap,k用来存储groupSizes[i],v存储list
//list为空,创建list,list.size == groupSizes[i],创建新的list
List<List<Integer>> res = new ArrayList<>();
Map<Integer, List<Integer>> map= new HashMap<>();
for(int i = 0; i < groupSizes.length; i++) {
if(!map.containsKey(groupSizes[i])) {
map.put(groupSizes[i],new ArrayList<>());
}
//这里出过错,Arraylist<integer>不能接受List父类类型
List<Integer> add = map.get(groupSizes[i]);
add.add(i);
if(add.size() == groupSizes[i]) {
//这里也出过错,如果存进去的不是一个新数组,会被清空
res.add(new ArrayList<>(add));
add.clear();
}
}
return res;
}
}