93. 递归实现组合型枚举 Java 题解

30 篇文章 1 订阅
11 篇文章 1 订阅

输入样例:

5 3

输出样例:

1 2 3 
1 2 4 
1 2 5 
1 3 4 
1 3 5 
1 4 5 
2 3 4 
2 3 5 
2 4 5 
3 4 5 

 解题思路:

组合型递归不同于全排列,全排列中的数字均相同,而组合数中各种组合只能出现一次。

  • 全排列:一个数组存储排好序的状态,一个数组用于标志是否访问(去重),还需要一个参数表示当前正枚举到的第几个元素(坑位)。
  • 组合数:一个数组存储排好序的状态,一个参数表示当前正枚举到第几个元素,还需要存储序列的前一个元素加一(表示从第几个元素开始组合达到“升序”效果

dfs的剪枝:当已经放好的数字的个数与还能存放的数的个数(相当于还有多少库存)之和,如果小于总坑位(相当于库存不够了,装不满了),则剪枝。

Java代码:

import java.io.*;

public class Main {
	static int n;
	static int m;
	static int []temp;
	static StringBuilder ans = new StringBuilder();
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] split = br.readLine().split(" ");
		n = Integer.parseInt(split[0]);
		m = Integer.parseInt(split[1]);
		temp = new int[n + 1];
		
		dfs(1, 1);
		System.out.print(ans);
	}
	
	public static void dfs(int u, int start) {//u表示即将往第u个位置放置
		if(u - 1 + n - start + 1 < m)
			return;//剪枝 当(u - 1):已经放号的个数 + (n - start + 1)还有的“库存”数
		          //两者相加 仍然不能填充坑位m,则剪去此枝
		if(u > m) {
			for(int i = 1; i <= m; i++) {
				ans.append(temp[i] + " ");
			}
			ans.append("\n");
			return;
		}
		
		for(int i = start; i <= n; i++) {
			temp[u] = i;
			dfs(u + 1, i + 1);
			temp[u] = 0;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值