每日一省之————递归法计算数组的所有排列组合

22 篇文章 0 订阅

本算法的目的: 给定一组数字,求这些数字的所有可能的排序组合。

算法内部逻辑:模拟人进行排列组合的过程。
1. 假设仅有2个数字, 则交换其位置,可以得到所有可能的组合,也即2组。
2. 假设有3个数字。则取出第1个数字,将第2和第3个数字交换位置后得到2种组合,然后在每种组合的开头插入第1个数字。得到了3个数字排列组合的其中两种;
然后取出第2个数字,将第1和第3个数字交换位置后得到2种组合,然后在每种组合的开头插入第2个数字。又得到了3个数字排列组合的其中两种
接着取出第3个数字,将第1和第2个数字交换位置后得到2种组合,然后在每种组合的开头插入第3个数字。又得到了3个数字排列组合的其中两种。至此,我们得到了3个数字的所有排列组合(6种)
3. 假设有4个数字。与3个数字一样,依次取出其中的某一个,将剩余的3个进行排列得到6种组合,然后在这6种组合的开头插入一开始取出的那个元素。这样,遍历这4个数字一遍之后,可以得到一共4*6=24种组合。
4. 假设有5个数字,同理:依据步骤2或3或4的逻辑,把大的数组化小,得到较小的数组返回的可能的排列组合后,再拼接成较大的数组的排列组合。
上述的分析过程表明可以使用递归的方法进行实现。具体实现代码如下:

public class Combine {

    public static void main(String[] args) {

        List<Integer> a = new ArrayList<Integer>(4);
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(4);
        a.add(5);

        int count = 0;

        List<List<Integer>> resList = combination(a);
        for (List<Integer> intList : resList) {
            count++;
            for (Integer i : intList) {
                System.out.print(i + ", ");
            }
            System.out.println();
        }
        System.out.println("一共有 " + count + " 种组合");
    }

    public static List<List<Integer>> combination(List<Integer> list) {

        if (list.size() == 1) {

            throw new IllegalArgumentException("the size of list must be lager than one");

        }

        List<List<Integer>> result = new ArrayList<List<Integer>>();

        int size = list.size();

        if (size == 2) {

            List<Integer> list1 = new ArrayList<>();
            list1.add(list.get(0));
            list1.add(list.get(1));

            List<Integer> list2 = new ArrayList<>();
            list2.add(list.get(1));
            list2.add(list.get(0));

            result.add(list1);
            result.add(list2);
        } else if (size > 2) {

            for (int i = 0; i < list.size(); i++) {

                List<Integer> copied = new ArrayList<Integer>(list);
                copied.remove(i);
                List<List<Integer>> subList = combination(copied);
                for (List<Integer> li : subList) {

                    li.add(0, list.get(i));
                    result.add(list);
                }
            }

        }

        return result;

    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值