c/c++全排列和组合的写法

全排列和组合本质都是DFS(Deapth First Search) 算法的思想。

  • 目标

    输出1-3全排列和组合.

    输出结果:

    在这里插入图片描述

  • 程序

#include <iostream>
	using namespace std;
	
	// 组合
	void dfs(int step, int goal, int cnt);
	// 排列
	void dfs(int goal, int step);
	
	void dfs2(int step, int goal, int cnt);
	
	int arr[100];
	bool visited[100];
	int main() {
	    memset(arr, 0, sizeof(arr));
	    std::cout << "Hello, World!" << std::endl;
	    dfs(0, 3, 0);
	
	
	    cout << "======" << endl;
	    memset(visited, 0, sizeof(visited));
	    dfs(3, 0);
	    return 0;
	}
	
	/**
	 *  组合: 1 - 3的组合
	 * @param step
	 * @param goal
	 * @param cnt
	 */
	void dfs(int step, int goal, int cnt){
	    if (step == goal) {
	        if (cnt == 0) {
	            cout << "null" << endl;
	            return;
	        }
	        for(int i = 0; i < cnt; i++) {
	            cout << arr[i] << " ";
	        }
	        cout << endl;
	        return;
	    }
	    dfs(step + 1, goal, cnt);
	    arr[cnt] = step + 1;
	    dfs(step + 1, goal, cnt + 1);
	    return;
	}
	/**
	 * 排列
	 * @param goal
	 * @param step
	 */
	void dfs(int goal, int step) {
	    if(step == goal) {
	        for (int i = 0; i < goal; i++) {
	            cout << arr[i] << " ";
	        }
	        cout << endl;
	        return;
	    }
	
	    for(int i = 0; i < goal; i++) {
	        if(visited[i]) {
	            continue;
	        }
	        visited[i] =  true;
	        arr[step] = i + 1;
	        dfs(goal, step + 1);
	        visited[i] = false;
	    }
	}

全排列

  • Python
def dfs(nums, used, res):
    if len(nums) == 0:
        res.append(nums[:])
        return
    for i in range(len(nums)):
        if not used[i]:
            used[i] = True
            dfs(nums[:i] + nums[i + 1:], used, res)
            used[i] = False


def perm(nums):
    res = []
    used = [False] * len(nums)
    dfs(nums, used, res)
    return res


print(perm([1, 2, 3]))

输出:

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
  • C++
#include <vector>

using namespace std;

void dfs(vector<int>& nums, vector<bool>& used, vector<vector<int>>& res) {
    if (nums.empty()) {
        res.push_back(nums);
        return;
    }
    for (int i = 0; i < nums.size(); i++) {
        if (!used[i]) {
            used[i] = true;
            dfs(nums, used, res);
            used[i] = false;
        }
    }
}

vector<vector<int>> perm(vector<int>& nums) {
    vector<vector<int>> res;
    vector<bool> used(nums.size(), false);
    dfs(nums, used, res);
    return res;
}

int main() {
    vector<int> nums = {1, 2, 3};
    vector<vector<int>> res = perm(nums);
    for (auto& v : res) {
        for (auto& i : v) {
            cout << i << " ";
        }
        cout << endl;
    }
    return 0;
}

组合

  • Python
def dfs(nums, used, res, n, k):
    if k == 0:
        res.append(nums[:])
        return
    for i in range(n):
        if not used[i]:
            used[i] = True
            dfs(nums[:i] + nums[i + 1:], used, res, n - 1, k - 1)
            used[i] = False


def combine(nums, n, k):
    res = []
    used = [False] * n
    dfs(nums, used, res, n, k)
    return res


print(combine([1, 2, 3], 3, 2))

输出:

[1, 2]
[1, 3]
[2, 1]
[2, 3]
[3, 1]
[3, 2]
  • C++
#include <vector>

using namespace std;

void dfs(vector<int>& nums, vector<bool>& used, vector<vector<int>>& res, int n, int k) {
    if (k == 0) {
        res.push_back(nums);
        return;
    }
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            used[i] = true;
            dfs(nums, used, res, n - 1, k - 1);
            used[i] = false;
        }
    }
}

vector<vector<int>> combine(vector<int>& nums, int n, int k) {
    vector<vector<int>> res;
    vector<bool> used(n, false);
    dfs(nums, used, res, n, k);
    return res;
}

int main() {
    vector<int> nums = {1, 2, 3};
    vector<vector<int>> res = combine(nums, 3, 2);
    for (auto& v : res) {
        for (auto& i : v) {
            cout << i << " ";
        }
        cout << endl;
    }
    return 0;
}

算法说明

  • 全排列

    全排列是指将给定的一个数字列表按照字典序排列,所有可能的排列。

    算法思路:

    1. 从第一个数字开始,依次选择数字放入排列中。
    2. 当选择了第 i 个数字后,需要将剩下的 (n - i) 个数字进行排列。
    3. 重复步骤 2,直到所有数字都选择完毕。
  • 组合

    组合是指从 n 个元素中选择 k 个元素,所有可能的组合。

    算法思路:

    1. 从第一个数字开始,依次选择数字放入组合中。
    2. 当选择了第 i 个数字后,需要将剩下的 (n - i) 个元素进行组合。
    3. 重复步骤 2,直到选择了 k 个数字。

    注意:在组合问题中,需要注意数字的顺序不重要。因此,在回溯过程中,需要将选择过的数字恢复。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早睡的叶子

你的鼓励就是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值