排列与组合

题目:由数字或字母组成的list,可以构成多少种包含n个元素的排列方式和组合方式?请列举出来。

排列思路:

            1.选出第一个元素

            2.递归排列第2到第n个元素

组合思路:

            1.如果组合中包含list的第一个元素

            2.如果组合中不包含list的第一个元素

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by WYS on 2018/5/14.
 */
public class ArrangeAndCombine {
    /**
     * 排列组合之排列
     * @param list 输入列表
     * @param n 需要排列的元素的个数
     * @param selected  已经排列好的元素集合
     * @param result    排列结果
     * @param <E>   排列元素的类型
     */
    public static<E> void arrange(List<E> list, int n, List<E> selected, List<List<E>> result){
        if(list.size()<n)
            return;
        if(n==0){
            result.add(new ArrayList<E>(selected));//注意:保存副本,不要保存原列表
            return ;
        }
        List<E> lCopy=new ArrayList<>(list);//将list复制到方法中
        for (int i = 0; i < lCopy.size(); i++) {
            E first=lCopy.get(i);            //选取第一个元素
            selected.add(first);
            lCopy.remove(i);    //将已排列的元素移除
            arrange(lCopy,n-1,selected,result); //排列其他元素
            lCopy.add(i,first); //复原
            selected.remove(selected.size()-1);
        }
    }

    /**
     * 排列组合之组合
     * @param list 待组合列表
     * @param n 需要组合的元素个数
     * @param selected  已经组合好的元素集合
     * @param result    结果
     * @param <E>   元素类型
     */
     public static<E> void combine(List<E> list, int n, List<E> selected, List<List<E>> result){
         if(list.size()<n)
             return;
         if(n==0){
             result.add(new ArrayList<E>(selected));
             return;
         }
         //组合中含有第一个元素
         selected.add(list.get(0));
         combine(list.subList(1,list.size()),n-1,selected,result);
         selected.remove(selected.size()-1);
         //组合中不含第一个元素
         combine(list.subList(1,list.size()),n,selected,result);
     }


    public static void main(String[] args) {
        //排列Integer
        List<Integer> list= Arrays.asList(1,2,3);
        List<List<Integer>> result=new ArrayList<>();
        arrange(list,2,new ArrayList<Integer>(),result);
        System.out.println(result);
        //排列Character
        List<Character> cList=Arrays.asList('a','b','c');
        List<List<Character>> cResult=new ArrayList<>();
        arrange(cList,2,new ArrayList<Character>(),cResult);
        System.out.println(cResult);
        //组合Integer
        result.clear();
        combine(list,2,new ArrayList<Integer>(),result);
        System.out.println(result);
        cResult.clear();
        combine(cList,2,new ArrayList<Character>(),cResult);
        System.out.println(cResult);
    }
}

结果:

[[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
[[a, b], [a, c], [b, a], [b, c], [c, a], [c, b]]
[[1, 2], [1, 3], [2, 3]]
[[a, b], [a, c], [b, c]]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值