1. 问题描述:
有 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/group-the-people-given-the-group-size-they-belong-to
2. 思路分析:
① 首先需要读懂题目的意思,题目的大概意思讲的是将用户组大小相同的对应下标放置在同一个集合中,比如测试用例中的groupSizes = [3,3,3,3,3,1,3],下标为0,1,2与3,4,6的都属于容量为3的用户组,因为最大的容量是3所以这些容量相同的下表属于两个用户组
② 一开始的时候想到使用map来放置数据,将用户组大小的相同的下表放置在一起,这样的话就比较好处理,map中键为用户组的大小,值为用户组中对应的下标
③ 对②中得到的map进行遍历,在遍历map的过程中需要将遍历map中的值并且将对应的下表放到List中,使用一个变量来记录当前的容量是否达到了当前用户组的最大值,假如达到了最大值那么需要新建一个List,这样的话当容量超过当前用户组的最大容量的时候可以放入到新的集合中去,并且加入到List的时候,List中的元素变化之后,List<List<Integer>>结果集中的List也会跟着变化的,所以当新建List的时候可以直接将List丢到List<List<Integer>>结果集中即可,所以这道题目本质上是使用了map的计数功能
④ 上面使用的是Java语言,下面使用python3进行解决,问题的思路是一样的,其中使用 到了list
作为 default_factory
,很轻松地将(键-值对组成的)序列转换为(键-列表组成的)字典,在遍历字典的时候使用python中的切片操作将同一用户大小的用户加入到一组中,官方文档对Collections.defaultdict的用法:https://docs.python.org/zh-cn/3.8/library/collections.html#collections.defaultdict
3. 代码如下:
class Solution {
public List<List<Integer>> groupThePeople(int[] groupSizes) {
Map<Integer, Deque<Integer>> map = new HashMap<>();
for (int i = 0; i < groupSizes.length; ++i){
Deque<Integer> deque = map.getOrDefault(groupSizes[i], new LinkedList<>());
deque.add(i);
map.put(groupSizes[i], deque);
}
/*遍历map*/
List<List<Integer>> res = new ArrayList<>();
for (Map.Entry<Integer, Deque<Integer>> entry : map.entrySet()){
/*遍历双端队列中的值*/
Deque<Integer> cur = entry.getValue();
int curVol = entry.getKey();
int count = 0;
List<Integer> newList = null;
while (!cur.isEmpty()){
if (count == 0 || count % curVol == 0){
newList = new ArrayList<>();
/*当这里加入newList到res的时候当newList变化的时候res也会跟着变化*/
res.add(newList);
}
/*放置当前的数字到List中去*/
newList.add(cur.poll());
++count;
}
}
return res;
}
}
Python3:
class Solution:
def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]:
groups = collections.defaultdict(list)
for i, _id in enumerate(groupSizes):
groups[_id].append(i)
# 构造一个空的列表
ans = list()
for gsize, users in groups.items():
for it in range(0, len(users), gsize):
# 这个是python3中的切片操作将同一组的用户加入到用户大小的一组list中
ans.append(users[it: it + gsize])
# print(ans)
return ans