41 Group the People Given the Group Size They Belong To

题目

There are n people whose IDs go from 0 to n - 1 and each person belongs exactly to one group. Given the array groupSizes of length n telling the group size each person belongs to, return the groups there are and the people’s IDs each group includes.

You can return any solution in any order and the same applies for IDs. Also, it is guaranteed that there exists at least one solution.

Example 1:

Input: groupSizes = [3,3,3,3,3,1,3]
Output: [[5],[0,1,2],[3,4,6]]
Explanation:
Other possible solutions are [[2,1,6],[5],[0,4,3]] and [[5],[0,6,2],[4,3,1]].

Example 2:

Input: groupSizes = [2,1,3,3,3,2]
Output: [[1],[0,5],[2,3,4]]

Constraints:

groupSizes.length == n
1 <= n <= 500
1 <= groupSizes[i] <= n

分析

题意:groupSizes中的数字表示:当前这个人所属的组的总人数。
[2,1,3,3,3,2]意思是
0号ID所属组的人数为2
1号ID所属组的人数为1
2号ID所属组的人数为3
3号ID所属组的人数为3
4号ID所属组的人数为3
5号ID所属组的人数为2

显然,0和5为一组,1单人一组,2,3,4为一组
所以结果为[[0,5],[1],[2,3,4]]

分析:

  1. 最简单的情况,相同groupSize的且个数等于groupSize的,对应下标一定是同组。如[2,2],groupsize=2,且个数为2,。
  2. 相同groupSize但个数不等于groupSize,此时个数一定是偶数倍可均分。如[2,2,2,2](不可能出现[2,2,2]),此时答案可以是0,1,2,3的任意两两组合。

算法:

1. 将groupSize中相同的值的"下标"放在一个数组中;
2. 如果“相同的值的个数”等于“相同值”,就把该数组加到结果集;
	否则:
		创建“相同值的个数/2”个数组,将下标均分在这些数组中,加入结果集;
3. 返回结果集

如何完成第一步?其实跟“找出数组中的所有相同值”方法一样:
遍历groupSize,如果groupSizes[i]==x,将i加入tmp数组中,直到i=groupSizes.length;最后返回该tmp数组

如何完成“下标均分”?
以[2,2,2,2]为例:
创建“相同值的个数/groupSizes[i]”个数组 --> 创建2个数组
每组均分“相同值”个数组 --> 即每组均分2个数据,[0,1] [2,3]

解答

这个算法有个错误,我改不出来。
在这里插入图片描述

返回的结果是正确的,但是多了,个数等于n * tmp.size() / groupSizes[i];
我试了试把创建tmp单独放在外面,个数为groupSizes去重后的大小,然而仍然不正确。

class Solution {
    public List<List<Integer>> groupThePeople(int[] groupSizes) {
        List<List<Integer>> res = new ArrayList<>();
        int n = groupSizes.length;
        int i=0;
        while(i<n){
            List<Integer> tmp = search(groupSizes[i],groupSizes);
            int k=0;
            if(tmp.size()==groupSizes[i])
                res.add(tmp);
            else{
                for(int j=0;j<tmp.size()/groupSizes[i];++j){
                    List<Integer> tmp2 = new ArrayList<>();
                    int flag=groupSizes[i];
                    while(flag>0){
                        tmp2.add(tmp.get(k++));
                        flag--;
                    }
                    res.add(tmp2);
                }
                k=0;
            }
            i++;
        }
        return res;
    }
    // 返回所有相同组数的下标(组员)
    public List<Integer> search(int x,int[] groupSizes){
        List<Integer> tmp = new ArrayList<>();
        for(int i=0;i<groupSizes.length;++i){
            if(x==groupSizes[i])
                tmp.add(i);
        }
        return tmp;
    }
}

看看评论区答案,算法类似,但是通过Map,更加简单。

class Solution {
        public List<List<Integer>> groupThePeople(int[] groupSizes) {
        // 存放结果集
        List<List<Integer>> res=new ArrayList<>();
        // key:组成员数,value:所有组员
        Map<Integer, List<Integer>> map=new HashMap<>();
        for(int i=0;i<groupSizes.length;i++) {
        	// 如果map中不存在这个成员组数,就加到map中
            if(!map.containsKey(groupSizes[i])) map.put(groupSizes[i], new ArrayList<>());
            // 获取当前成员小组
            List<Integer> cur=map.get(groupSizes[i]);
            // 把当前成员加到小组中
            cur.add(i);
            // 如果当前组成员数等于实际组成员数
            if(cur.size()==groupSizes[i]) {
                res.add(cur);
                // 将当前组移除
                map.remove(groupSizes[i]);
            }
            // 如果当前组成员数不等于实际组成员数,也就是分析中算法的第二种情况,此时回到循环开头map.containsKey判断就不成立,就不会创建新的list。通过这种方式,解决了我上述算法的问题。
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值