LeetCode——Combinations

Given two integers n and k, return all possible combinations of k numbers out of 1 … n.

  • Example:
    Input: n = 4, k = 2
    Output:
    [
    [2,4],
    [3,4],
    [2,3],
    [1,2],
    [1,3],
    [1,4],
    ]

解法一——深度优先搜索

求排列组合第一个想到的就是用深度优先搜索写出所有可能的组合

public List<List<Integer>> combine(int n, int k) {
		List<List<Integer>> res=new ArrayList<List<Integer>>();
		combinecore(n,k,1,res,new ArrayList<Integer>());
		return res;
    }

	private void combinecore(int n, int k, int level, List<List<Integer>> res, ArrayList<Integer> out) {
		// TODO Auto-generated method stub
		if(out.size()==k)
		{
			res.add(new ArrayList<Integer>(out));
			return;
		}
		for(int i=level;i<=n;i++)
		{
		//如果n-i<k-(out.size()+1),则提前退出。比如,i=4,4后面没有数字可选了,
		//即n-i=0,而此时out.size()还为0,即使加入4这个数字,也只是1,即k-(out.size()+1)=1,
		//那么它还需要一个数字,而实际上已经没有数字可选了,所以可以提前退出
		//加上这个剪枝操作后,程序运行时间由27ms提升到了1ms
            if(out.size()+n-i+1<k)
                return;
			out.add(i);
			combinecore(n, k, i+1, res, out);
			out.remove(out.size()-1);
		}
	}

Runtime: 1 ms, faster than 100.00% of Java online submissions for Combinations.
Memory Usage: 37.8 MB, less than 100.00% of Java online submissions for Combinations.

解法二

这种解法利用了排列组合的性质,即从四个里面选三个的组合可以分为选4和不选4,如果选4,那么从3个里面选一个然后再加上4;如果不选4,则从3个里面选2个,即C(4,3)=C(3,2)+C(3,1),扩展到n和k的话,这个公式可以写成:
C(n,k)=C(n-1,k-1)+C(n-1,k)

public List<List<Integer>> combine(int n, int k) {
		if(k>n||k<0)
			return new ArrayList<List<Integer>>();
		if(k==0)
		{
			List<Integer> out=new ArrayList<Integer>();
			List<List<Integer>> res=new ArrayList<List<Integer>>();
			res.add(out);
			return res;
		}
		List<List<Integer>> res=combine(n-1, k-1);
		for(List<Integer> a:res)
			a.add(n);
		for(List<Integer> a:combine(n-1, k))
			res.add(a);
		
		return res;
	}

Runtime: 3 ms, faster than 92.58% of Java online submissions for Combinations.
Memory Usage: 38 MB, less than 100.00% of Java online submissions for Combinations.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值