关于组合问题的一种巧妙方法

本文介绍了一种巧妙的方法,通过将组合问题转化为m位二进制数中选取n位1的操作,来解决从m个元素中选取n个元素的所有组合问题。详细解释了如何通过循环遍历所有可能的二进制数,并使用无符号右移和按位与运算来判断哪些位是1,以此来确定组合情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在算法设计与分析里,组合排列(或者表面像排列组合)的问题很好的解决方法主要是回溯法,广度优先遍历法。
     这里提供关于组合问题一种巧妙的解决办法。比如我们要从m个元素里取n个元素的所有组合。
     我们用一个m位二进制数代表m个元素(一位代表一个元素)。取n个元素可以看做是这个m位二进制数中有n位的值为1.
      一个m位二进制数可以代表2的m次方个值,(代表m个元素所有组合的情况)
    /**
* 从m个数里取n个数的组合的个数,这里i并不是一个m位数,只是使用了i最右边的m位数
* 思路:
* @param m
* @param n
* @return
*/
public static int getCombinations(int m,int n){
int total=0;
for(long i=0l;i<Math.pow(2, m);++i){
int count=0;
//j=0表示右边第一位,j=1表示右边第二位,
for (int j = 0; j <m; j++) {
                             //>>>无符号右移,左边填充0,i>>>j先运算,把我们要考核的哪一位移到最右边,然后与1进行&运算,即可知道我们考核的那一位的值。 
if((i>>>j&1)==1){
++count;
}
if(count>n){
break;
}
}
if(count==n){
++total;
}
}
return total;
}

    /*  取组合方法
     *     参数: list ---- 原始集合
     *     返回:  包含所有组合的集合
     */
    public static List<List<Object>> getCombinations(List<Object> list) {
        List<List<Object>> result = new ArrayList<List<Object>>();
        long n = (long)Math.pow(2,list.size());
        List<Object> combine;
        for (long l=0L; l<n; l++) {
            combine = new ArrayList<Object>();
            for (int i=0; i<list.size(); i++) {
                if ((l>>>i&1) == 1)
                    combine.add(list.get(i));
            }
            result.add(combine);
        }
        return result;
    } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值