当前位置: 面试刷题>> 第k个组合 (经典算法题500道)


题目描述

给定两个整数 nk,其中 1 ≤ k ≤ C(n, k)C(n, k) 表示从 n 个不同元素中取出 k 个元素的组合数)。请编写一个算法来找出所有可能的 k 个数的组合中的第 k 个组合。

注意

  • 组合中的元素应该是按升序排列的。
  • k 个组合是按照字典序排列的。

示例

假设 n = 4k = 5(注意:通常 k 不会超过 C(n, k),但这里为了说明,我们假设一个小的 k 值以展示如何操作,实际情况下需要处理 k 的有效范围)。然而,由于 C(4, 2) = 6,并且 k = 5,这意味着我们实际上要找的是 {2, 3} 这个组合(因为 {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4} 是按字典序排列的所有组合,第5个是 {2, 3})。但更常见的题目设定是 k 不会超出实际的组合数。

为了简化,我们考虑 n = 4, k = 3,则第3个组合是 {1, 3}

PHP 示例代码

function getKthCombination($n, $k) {
    $result = [];
    $start = 1;
    $combinations = 0;

    while ($k > 0) {
        $max = min($n, $start + $k - 1);
        $combinations += $max - $start + 1;

        if ($combinations >= $k) {
            $result[] = $start + $k - $combinations;
            $k--;
        }

        $start++;
    }

    rsort($result); // 因为我们是从后往前选的,所以需要反转结果
    return $result;
}

// 示例
$n = 4;
$k = 3;
$combination = getKthCombination($n, $k);
print_r($combination); // 输出: Array ( [0] => 1 [1] => 3 )

注意:上述 PHP 代码是基于一种简化的思路,并不直接处理所有可能的组合,而是利用了组合的性质来直接找到第 k 个组合。直接处理所有组合并排序的方法在 n 较大时会非常低效。

Python 示例代码

Python 提供了更直接的方法来处理组合,使用 itertools.combinations 生成所有组合,然后取第 k-1 个(因为索引从0开始)。

from itertools import combinations

def getKthCombination(n, k):
    all_combinations = list(combinations(range(1, n + 1), k))
    return all_combinations[k - 1]

# 示例
n = 4
k = 3
combination = getKthCombination(n, k)
print(combination)  # 输出: (1, 2, 3)

JavaScript 示例代码

JavaScript 中没有内置的 combinations 函数,但我们可以使用递归或迭代来生成组合,并找到第 k 个。

function getKthCombination(n, k) {
    let result = [];
    let start = 1;
    let combinations = 0;

    while (k > 0) {
        const max = Math.min(n, start + k - 1);
        const count = max - start + 1;
        combinations += count;

        if (combinations >= k) {
            result.push(start + k - combinations);
            k--;
        }

        start++;
    }

    result.sort((a, b) => b - a); // 反转结果
    return result;
}

// 示例
const n = 4;
const k = 3;
const combination = getKthCombination(n, k);
console.log(combination); // 输出: [1, 3]

以上示例代码均旨在展示如何找到第 k 个组合,但请注意,对于非常大的 nk,直接生成所有组合的方法可能非常低效。在实际应用中,应考虑使用更高效的算法,如基于组合数性质的算法。

推荐面试题