递归实现组合型枚举

import java.util.Scanner;

public class Main {
    static int n;//有n个数
    static int m;//取m个
    static int a[];//存放每次的组合结果
    static boolean used[];//0~n-1分别存放1~n,表示当前数字是否已进入排列序列,true表示已用,false表示未用
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        m = scan.nextInt();
        a = new int[m];
        used = new boolean[n];
        dfs(0);
        scan.close();
    }
    //k表示当前递归到第几个位置,对每个位置进行递归,依次填入数字,直到递归到最后一个位置并填入数字
    public static void dfs(int k){
        if(k == m){//边界,表示递归到最后一个位置,将递归结果输出
            for(int i = 0; i < m; i++){
                System.out.print(a[i]+" ");
            }
            System.out.println();
            return;
        }
        //遍历哪些数还没进入当前排列序列,将当前位置所有可能填入的数字进行for填入,并递归到下一个位置
        for(int i = (k==0?0:a[k-1]);i < n;i ++){
        //模板是全排列的板子,相较于全排列的不同点:这里的i取值通过画递归搜索树发现第i+1个位置的元素不能比第i个位置的元素小
            if(used[i] == false){//元素i+1未用
                //将i+1填入当前位置
                a[k] = i + 1;
                //置元素i+1已用
                used[i] = true;
                //递归到下一个排列位置,直到所有位置均填入数字
                dfs(k+1);
                //回溯,恢复现场信息,因为下一层for循环又是另一种情况(当前位置不填入i+1,而是填入下一层for循环得到的数)
                used[i] = false;
                a[k] = 0;
            }
        }
    }
}  

你可能感兴趣的:(算法,java,深度优先,算法)