• 【数组】用户分组 哈希表


    题目描述

    有n个人被分成数量未知的组。每个人都被标记为一个从 0 到 n - 1 的唯一ID。

    给定一个整数数组 groupSizes ,其中groupSizes[i]是第 i 个人所在的组的大小。例如,如果groupSizes[1] = 3,则第 1 个人必须位于大小为 3 的组中。

    返回一个组列表,使每个人 i 都在一个大小为groupSizes[i]的组中。

    每个人应该恰好只出现在一个组中,并且每个人必须在一个组中。如果有多个答案,返回其中任何一个。可以保证给定输入至少有一个有效的解。

    示例 1:

    输入:groupSizes = [3,3,3,3,3,1,3]
    输出:[[5],[0,1,2],[3,4,6]]

    解题思路

    这道题可以先做排序,对排序后结果进行分组:

    • 准备一个数组,array[][],分别记录groupSize和下标;
    • 按照groupSize对array进行排序;
    • 准备一个List> res,第一次或者是list.size()==groupSize则创建一个新的list。

    代码实现如下:

    1. import java.util.ArrayList;
    2. import java.util.Arrays;
    3. import java.util.Comparator;
    4. import java.util.List;
    5. class Solution2 {
    6. public List> groupThePeople(int[] groupSizes) {
    7. int[][] array = new int[groupSizes.length][2];
    8. for (int i = 0; i < groupSizes.length; i++) {
    9. array[i][0] = groupSizes[i];
    10. array[i][1] = i;
    11. }
    12. Arrays.sort(array, new Comparator<int[]>() {
    13. @Override
    14. public int compare(int[] o1, int[] o2) {
    15. return o1[0] - o2[0];
    16. }
    17. });
    18. ArrayList> res = new ArrayList<>(groupSizes.length);
    19. res.add(new ArrayList<>());
    20. for (int i = 0; i < array.length; i++) {
    21. int[] v = array[i];
    22. int size = v[0];
    23. int index = v[1];
    24. List list = res.get(res.size() - 1);
    25. list.add(index);
    26. if (i >= array.length - 1) {
    27. break;
    28. }
    29. if (size <= list.size()) {
    30. res.add(new ArrayList<>());
    31. }
    32. }
    33. return res;
    34. }
    35. public static void main(String[] args) {
    36. Solution2 solution = new Solution2();
    37. System.out.println(solution.groupThePeople(new int[]{3, 3, 3, 3, 3, 1, 3}));
    38. }
    39. }

    上述这种实现方式耗时上不是最优的,排序就需要O(N*LogN)。

    为了降低时间复杂度,我不再进行排序,切换使用MAP来解决问题,为了最大化降低时间复杂度,自己实现了一个简单的哈希表:

    1. class MyMap {
    2. final List[] array;
    3. public MyMap(int length) {
    4. this.array = new List[length + 1];
    5. }
    6. public List get(int key) {
    7. return this.array[key];
    8. }
    9. public void put(int key, List list) {
    10. this.array[key] = list;
    11. }
    12. }

    基于哈希表的解题思路:

    • 遍历数组,获取groupSize和下标i;
    • 从哈希表中获取groupSize对应的List,如果List为空则新建,如果List不为空则添加下标i
    • 判断List的大小是不是大于等于groupSize,如果大于等于则重新创建List;

    按照上述思路代码实现:

    1. import java.util.ArrayList;
    2. import java.util.List;
    3. class Solution4 {
    4. public List> groupThePeople(int[] groupSizes) {
    5. MyMap map = new MyMap(groupSizes.length);
    6. List> res = new ArrayList<>();
    7. for (int i = 0; i < groupSizes.length; i++) {
    8. int groupSize = groupSizes[i];
    9. List list = map.get(groupSize);
    10. if (list == null) {
    11. map.put(groupSize, list = new ArrayList<>(groupSize));
    12. }
    13. list.add(i);
    14. if (list.size() >= groupSize) {
    15. res.add(list);
    16. map.put(groupSize, new ArrayList<>(groupSize));
    17. }
    18. }
    19. return res;
    20. }
    21. class MyMap {
    22. final List[] array;
    23. public MyMap(int length) {
    24. this.array = new List[length + 1];
    25. }
    26. public List get(int key) {
    27. return this.array[key];
    28. }
    29. public void put(int key, List list) {
    30. this.array[key] = list;
    31. }
    32. }
    33. public static void main(String[] args) {
    34. Solution4 solution = new Solution4();
    35. System.out.println(solution.groupThePeople(new int[]{3, 3, 3, 3, 3, 1, 3}));
    36. }
    37. }

    总结

    这道题在解答思路上要注意一下,一定要用通过哈希表来做,因为排序耗时和哈希表操作的时间复杂度差别很大;

    上述代码哈希表,还可以进一步改写,直接使用局部变量数组来做,时间上还能有所下降,但是均无法到达最快耗时,欢迎大家提供更快更好的思路。

  • 相关阅读:
    java基于微信小程序的在线外卖订餐系统 uniapp
    Triloga 任务——Benja 系列
    UDP丢包替代:用PCAP实现C/C++以太网SDR吞吐
    Android P 禁用非官方API
    AI视界周刊第 1 期:最具性价比 GPT-4o mini 发布、大模型集体失智、语言模型安全漏洞
    linux redis string 乱序版
    卷积神经网络总结
    orchestrator数据库高可用组件搭建
    Python与ArcGIS系列(十一)SearchCursor方法
    基于Springboot+Vue实现前后端分离商城管理系统
  • 原文地址:https://blog.csdn.net/weiliuhong1/article/details/126311636