组合m个数.java 2.6 KB
Newer Older
qq_36480062's avatar
commit  
qq_36480062 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
package 递归;

/**
 * 93. 递归实现组合型枚举
 *  1~n  n 个整数中随机选出 m 输出所有可能的选择方案
 * 输入格式
 * 两个整数 n,m ,在同一行用空格隔开
 * 输出格式
 * 按照从小到大的顺序输出所有方案每行1个
 * 首先同一行内的数升序排列相邻两个数用一个空格隔开
 * 其次对于两个不同的行对应下标的数一一比较字典序较小的排在前面例如1 3 5 7排在1 3 6 8前面)。
 * 数据范围
 * n>0 ,
 * 0mn ,
 * n+(nm)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
 */
public class 组合m个数 {
    public static void main(String[] args) {
//        Scanner sc = new Scanner(in);
//        n = sc.nextInt();
//        m = sc.nextInt();
        long l = System.nanoTime();
qq_36480062's avatar
c  
qq_36480062 已提交
36
        dfs(0, 0, 0);
qq_36480062's avatar
commit  
qq_36480062 已提交
37
        long e = System.nanoTime();
qq_36480062's avatar
c  
qq_36480062 已提交
38 39 40 41 42 43
        System.out.println((e - l) / 1e9);
        l = System.nanoTime();
        dfs(0, 0);
        e = System.nanoTime();
        System.out.println((e - l) / 1e9);

qq_36480062's avatar
commit  
qq_36480062 已提交
44 45 46

    }

qq_36480062's avatar
c  
qq_36480062 已提交
47 48 49
    static int m = 3, n = 12;
    static int[] arr = {23, 1, 2, 4, 7, 3, 6, 8, 1, 5, 12,13};
    static int[] vis = new int[12];
qq_36480062's avatar
commit  
qq_36480062 已提交
50 51 52 53 54 55

    //枚举到第u位 ,sum是当前选了几个,state是vis数组
    static void dfs(int u, int sum, int state) {
        if (sum + (n - u) < m) return;//就是n-u就是剩余还没有选的数字的数量,
        // sum+(n-u)<m就是剩余的数字都选上,也不够m个数字,所以剪枝
        if (sum == m) {//选了m个就输出
qq_36480062's avatar
c  
qq_36480062 已提交
56 57 58 59 60 61
//            for (int i = 0; i < n; i++) {
//                if ((state >> i & 1) == 1) {
//                    System.out.print(arr[i] + " ");
//                }
//            }
//            System.out.println();
qq_36480062's avatar
commit  
qq_36480062 已提交
62 63 64 65 66 67
            return;
        }
        if (u == n) return;//所有数字都选完了
        dfs(u + 1, sum + 1, state | (1 << u));//能选就先选,保持字典序!!!
        dfs(u + 1, sum, state);//选不选第u个数
    }
qq_36480062's avatar
commit  
qq_36480062 已提交
68 69 70 71 72 73

    //一共有n个数据,选m个
    //u是第几个,k是当前一共选了多少个
    static void dfs(int u, int k) {
        if (k + n - u < m) return;
        if (k == m) {
qq_36480062's avatar
c  
qq_36480062 已提交
74 75 76 77 78
//            for (int i = 0; i < n; i++) {
//                if (vis[i] == 1)
//                    System.out.print(arr[i] + " ");
//            }
//            System.out.println();
qq_36480062's avatar
commit  
qq_36480062 已提交
79 80 81 82 83 84 85 86
            return;
        }
        if (u == n) return;//n个数据都用完了
        vis[u] = 1;//带上第u个数,前往下一层
        dfs(u + 1, k + 1);//选第u个
        vis[u] = 0;
        dfs(u + 1, k);
    }
qq_36480062's avatar
commit  
qq_36480062 已提交
87
}