快速找到最佳组合方式,无需重复计算

问题描述 投票:0回答:1

我想找到此类数学问题的最佳快速解决方案:

假设房间里有 5 个人。每个人都必须握手 彼此。它带来了多少种组合?

虽然我知道组合公式

enter image description here

我使用这个快速阶乘函数:

func factorial(n: Int) -> Int {
    return n == 0 ? 1 : n * factorial(n — 1)
}

有没有办法建立一个函数,不仅通过替换上面公式中的变量来计算组合?

注意:

我认为这不是最优化的方式:

let combinations = factorial(n: 5)/(factorial(n: 2)*factorial(n: 3)) // 10
swift math factorial
1个回答
5
投票

k
中选择
n
项的方法数量由下式给出 二项式系数
C(n, k)
乘法公式 对于非负
n
k
可以在 Swift 中实现为

/// Binomial coefficient C(n, k) for non-negative integers n, k.
func binomial(_ n: Int, _ k: Int) -> Int {
    precondition(k >= 0 && n >= 0)
    if (k > n) { return 0 }
    var result = 1
    for i in 0 ..< min(k, n-k) {
        result = (result * (n - i))/(i + 1)
    }
    return result
}

这比使用阶乘的公式“更好”

C(n, k) = n! / (k! * (n-k)!)

从某种意义上说,中间值不会变得那么大。 (但是它可以溢出,例如

C(70, 35) = 112186277816662845432

超出了64位整数的范围!)

示例(帕斯卡三角形):

for n in 0...7 {
    print((0...n).map { k in binomial(n, k) })
}

// Output:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]

在您的特殊情况下,

n
之间的握手次数 人是
C(n, 2) = n*(n-1)/2
。你可以用上面的方法来计算 功能或只是与

func handshakes(n: Int) -> Int {
    return n*(n-1)/2
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.