由于给定的输入一定存在有效的解,因此对于数组 groupSizes 中的每个元素 x,当 x 在数组中出现 y 次时,y 一定能被 x 整除,且大小为 x 的组有 \dfrac{y}{x 个。
首先将每个人的编号按照组的大小划分,使用哈希表记录每个组的大小对应的所有人的编号。然后遍历哈希表,对于大小为 x 的组,得到对应的所有人编号列表,将列表的大小记为 y,则 y 一定能被 x 整除,将列表分成 \dfrac{y}{x 个大小为 x 的组,并将每个组添加到答案中。遍历结束之后,即完成分组。
classSolution: defgroupThePeople(self, groupSizes: List[int]) -> List[List[int]]: groups = defaultdict(list) for i, size inenumerate(groupSizes): groups[size].append(i) ans = [] for size, people in groups.items(): ans.extend(people[i: i + size] for i inrange(0, len(people), size)) return ans
publicclassSolution { public IList<IList<int>> GroupThePeople(int[] groupSizes) { Dictionary<int, IList<int>> groups = new Dictionary<int, IList<int>>(); int n = groupSizes.Length; for (int i = 0; i < n; i++) { int size = groupSizes[i]; groups.TryAdd(size, new List<int>()); groups[size].Add(i); } IList<IList<int>> groupList = new List<IList<int>>(); foreach (KeyValuePair<int, IList<int>> pair in groups) { int size = pair.Key; IList<int> people = pair.Value; int groupCount = people.Count / size; for (int i = 0; i < groupCount; i++) { IList<int> group = new List<int>(); int start = i * size; for (int j = 0; j < size; j++) { group.Add(people[start + j]); } groupList.Add(group); } } return groupList; } }
var groupThePeople = function(groupSizes) { const groups = newMap(); const n = groupSizes.length; for (let i = 0; i < n; i++) { const size = groupSizes[i]; if (!groups.has(size)) { groups.set(size, []); } groups.get(size).push(i); } const groupList = []; for (const [size, people] of groups.entries()) { const groupCount = Math.floor(people.length / size); for (let i = 0; i < groupCount; i++) { const group = []; const start = i * size; for (let j = 0; j < size; j++) { group.push(people[start + j]); } groupList.push(group); } } return groupList; };
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12
funcgroupThePeople(groupSizes []int) (ans [][]int) { groups := map[int][]int{} for i, size := range groupSizes { groups[size] = append(groups[size], i) } for size, people := range groups { for i := 0; i < len(people); i += size { ans = append(ans, people[i:i+size]) } } return }
复杂度分析
时间复杂度:O(n),其中 n 是数组 groupSize 的长度。需要遍历数组一次得到每个组的大小对应的所有人的编号,然后需要遍历所有元素完成分组。
空间复杂度:O(n),其中 n 是数组 groupSize 的长度。空间复杂度主要取决于哈希表,哈希表需要 O(n) 的空间记录每个组的大小对应的所有人的编号。