牛客2017校招真题在线编程-组合求和

https://www.nowcoder.com/practice/11cc498832db489786f8a03c3b67d02c?tpId=85&&tqId=29869&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking

题目描述
输入两个整数 n 和 m,从数列1,2,3…….n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来

输入描述:
每个测试输入包含2个整数,n和m

输出描述:
按每个组合的字典序排列输出,每行输出一种组合

示例1
输入
5 5

输出
1 4
2 3
5

题解:

组合问题
注意和排列的区别:
每次递归只能从选取字符后面的字符中选择,不然会有重复。
只要新生成的字符不为 “” , 即有一个结果,但不能直接返回,还要组合后面的字符。

排列、组合问题详见 https://blog.csdn.net/zxm1306192988/article/details/81060719

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int m = input.nextInt();
        if (m <= 0 || n <= 0) {
            return;
        }
        List<Integer> list = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            list.add(i);
        }
        dfs(list, new ArrayList<Integer>(), m);

    }

    private static void dfs(List<Integer> list, List<Integer> sub, int m) {
        int sum = 0;
        for (int i = 0; i < sub.size(); i++) {
            sum += sub.get(i);
        }
        if (sum == m) {
            for (int i = 0; i < sub.size(); i++) {
                System.out.print(sub.get(i));
                if (i != sub.size() - 1) {
                    System.out.print(" ");
                }
            }
            System.out.println();
        }
        for (int i = 0; i < list.size(); i++) {
            sub.add(list.get(i));
            dfs(list.subList(i+1, list.size()), sub, m);
            sub.remove(sub.size()-1);
        }

    }
}

猜你喜欢

转载自blog.csdn.net/zxm1306192988/article/details/81321559