C++实现数字组合(递归)

一、题目

设整数x1,x2,...xn已存放在数组A中,编写一递归过程,输出从这n个数中取出所有k个数的所有组合(k<=n)。例如,若A中存放的数是1,2,3,4,5,且k为3,则输出结果为:543,542,541,532,531,521,432,431,421,321。

二、问题分析

从数组中选择 k 个元素的所有组合,要求组合元素按原数组的逆序排列(即从后往前选元素,形成降序组合)。例如数组 [1,2,3,4,5],选3个元素时,第一个组合为 543(选最后一个元素5,倒数第二个4,倒数第三个3)。

三、递归策略

  1. 逆向选择:从数组末尾开始逐个选择元素,确保组合降序。

  2. 分步决策

    • 每一步选择一个元素加入临时组合。

    • 递归选择剩余元素中的前部分(即更小的元素)。

  3. 终止条件:已选满 k 个元素时,输出当前组合。

四、时间复杂度

组合数为 C(n, k),时间复杂度为 O(C(n, k) * k)

五、代码实现

#include <iostream>

using namespace std;

/**
 * 递归生成所有k个元素的组合(按逆序选择)
 * @param A 输入数组(必须升序排列)
 * @param start 当前可选的起始索引(从右向左选)
 * @param n 数组长度
 * @param k 需要选择的元素个数
 * @param currentCount 已选元素数量
 * @param temp 临时存储当前组合的数组
 */
void combine(int A[], int start, int k, int currentCount, int temp[]) {
    if (currentCount == k) {
        // 输出当前组合
        for (int i = 0; i < k; i++) {
            cout << temp[i];
        }
        cout << endl;
        return;
    }

    // 从start到0逆向选择元素
    for (int i = start; i >= 0; i--) {
        temp[currentCount] = A[i];  // 选择当前元素
        combine(A, i - 1, k, currentCount + 1, temp); // 递归选剩余元素
    }
}

int main() {
    int n, k;
    cout << "输入数组长度n: ";
    cin >> n;
    int A[n];
    cout << "输入" << n << "个升序整数: ";
    for (int i = 0; i < n; i++) {
        cin >> A[i];
    }
    cout << "输入k值: ";
    cin >> k;

    int temp[k];  // 临时存储组合
    combine(A, n - 1, k, 0, temp);  // 从最后一个元素开始选

    return 0;
}

测试用例

输入1:

输入数组长度n: 5
输入5个升序整数: 1 2 3 4 5
输入k值: 3

输出1:

输入2:

输入数组长度n: 4
输入4个升序整数: 2 5 7 9
输入k值: 2

输出2:

六、题目关键点

  1. 数组必须升序
    代码假设输入数组是升序的,这样从后往前选元素才能得到降序组合。若数组无序,需先排序。

  2. 递归终止条件
    当已选元素数量 currentCount 等于 k 时,输出临时数组 temp 中的组合。

  3. 逆向遍历保证顺序
    通过 for (int i = start; i >= 0; i--) 从右向左遍历,确保组合按逆序生成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值