《仨》 简单算法--1.递归-中

138 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

(3)递归实现组合型枚举

www.acwing.com/problem/con…

从 1∼n1∼n 这 nn 个整数中随机选出 mm 个,输出所有可能的选择方案。

输入格式

两个整数 n,mn,m ,在同一行用空格隔开。

输出格式

按照从小到大的顺序输出所有方案,每行 11 个。

首先,同一行内的数升序排列,相邻两个数用一个空格隔开。

其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如 1 3 5 7 排在 1 3 6 8 前面)。

数据范围

n>0n>0 , 0≤m≤n0≤m≤n , n+(n−m)≤25n+(n−m)≤25

输入样例:

 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 

思考题:如果要求使用非递归方法,该怎么做呢?

递归实现组合型枚举和递归实现指数型枚举的做法是一样的,只是需要控制位数,递归出口是当达到规定的位数的时候(即 sum = m) ,或者实现不了规定位数的时候(sum + n - deep < m ),代码如下

 import java.io.*;
 import java.util.*;
 ​
 public class Main{
     static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
     static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
     static int n = 0;
     static int m = 0;
     static void dfs(int deep,int sum,int status) throws IOException{
         if(sum + n - deep < m) return;
         if(sum == m) {
             for(int i = 0; i < n; ++i) {
                 if((status >> i & 1) == 1) {
                     out.write(i + 1 + " ");
                 }
             }
             out.write("\n");
             return ;
         }
         dfs(deep + 1,sum + 1,status | 1 << deep);
         dfs(deep + 1,sum,status);
     }
     public static void main(String[] args) throws Exception{
         String[] str = in.readLine().split(" ");
         n = Integer.parseInt(str[0]);
         m = Integer.parseInt(str[1]);
         dfs(0,0,0);
         in.close();
         out.close();
     }
 ​
 }

(4) 递归实现排列型枚举

题目描述 把 1~n 这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序。

输入格式 一个整数n。

输出格式 按照从小到大的顺序输出所有方案,每行1个。 首先,同一行相邻两个数用一个空格隔开。 其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。 数据范围 1≤n≤9 输入样例: 3 输出样例: 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1

 import java.io.*;
 import java.util.*;
 ​
 public class Main{
     static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
     static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
     static int n = 0;
     static int m = 0;
     static boolean[] vis = new boolean[15];
     static int[] a = new int[15];
     static void dfs(int deep) throws IOException{
         if(deep == n) {
             for(int i = 0; i < n; ++i) {
                 out.write(a[i] + " ");
             }
             out.write("\n");
             return ;
         }
         for(int i = 1; i <= n; ++i) {
             if(!vis[i]) {
                 vis[i] = true;
                 a[deep] = i;
                 dfs(deep + 1);
                 vis[i] = false;
             }
         }
     }
     public static void main(String[] args) throws Exception{
         String[] str = in.readLine().split(" ");
         n = Integer.parseInt(str[0]);
         dfs(0);
         in.close();
         out.close();
     }
 ​
 }