Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

组合 Combinations 的动态规划解法 #44

Open
Shellbye opened this issue Jan 9, 2019 · 0 comments
Open

组合 Combinations 的动态规划解法 #44

Shellbye opened this issue Jan 9, 2019 · 0 comments

Comments

@Shellbye
Copy link
Owner

Shellbye commented Jan 9, 2019

在写上一篇博客( #43 )的时候,想要用一种暴力的解法去完成,但是遇到一个问题,就是求一个数组里面所有数的组合,于是就先来看组合了。

题目

给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

动态规划解法

动态规划解法的关键,依然是找到递推公式,也就是拆分子问题的方式,在本题中,我们可以利用组合的计算公式

C(n,k)=C(n-1,k-1)+C(n-1,k)

这个公式的物理意义:n个数中选k个,可以分为“包含n这个数字(剩下的n-1个中再取剩下的k-1)”和“不包含n这个数字(剩下的n-1个中全完全部k个)”两类,分别表示为C(n-1,k-1)和`C(n-1,k)·。有了上面的公式,那么代码也相对简单了许多

class Solution {
    public List<List<Integer>> combine(int n, int k) {
        if (n == k) {
            List<Integer> row = new ArrayList<>();
            for (int i = 1; i <= n; i++) {
                row.add(i); // select all
            }
            List<List<Integer>> ret = new LinkedList<>();
            ret.add(row);
            return ret;
        }
        if (k == 0) {
            List<Integer> row = new ArrayList<>();
            List<List<Integer>> ret = new LinkedList<>();
            ret.add(row);
            return ret;
        }

        List<List<Integer>> ret = this.combine(n - 1, k - 1);
        for (List<Integer> list : ret) {
            list.add(n);
        }
        ret.addAll(this.combine(n - 1, k));
        return ret;
    }
}

这里需要稍微说一下n == k内部的for循环里面,是把这次的组合的结果存储了起来,我刚开始看的时候,以为应该是row.add(1);,理解其实有误,这里并不是求有几种组合方法,而是要展示具体的组合结果。
还有就是最后一个循环内部的list.add(n);,因为this.combine(n - 1, k - 1);里面的所有组合都没有n,这里需要都给补上,这个公式C(n,k)=C(n-1,k-1)+C(n-1,k)只是保证了数量上的相等,所以这里需要单独添加n;但是在this.combine(n - 1, k)中,因为本身就没有包含n,所以就不需要额外的添加工作了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant