C++ dfs搜索枚举(四十九)【第九篇】

今天我们接着来学习dfs(枚举)

1.枚举排列

在之前的搜索枚举中,我们并没有考虑选入物品的 排列顺序。但在一些题目中,会要求考虑给定数字或物品的排列,这种排列可以是在

n 个中的所有符合要求的全排列,也可以是在

n 中找到长度为 k 的排列。

如果使用我们之前的搜索枚举方法,我们发现难以用参数标记原数组中数字的选取情况,那么我们就需要一个全局的布尔数组,帮助我们标记哪些数字已经被选入了排列。另一方面,由于我们使用了这样的全局标记数组,那么必然在搜索时使用到 回溯 技巧,在这个分支的搜索结束后,将标记数组还原。

若要输出 n 个数字全排列,在 dfs 数组中需要的参数需要包含已经选入的数字,在选取当前位数字后进行搜索后,要注意进行回溯

cpp 复制代码
int n;
int per[N];
bool vis[N];
void dfs (int dep) {
    if (dep == n) {
        for (int i = 0; i < n; i++) {
            cout << per[i] << " ";
        }
        cout << endl;
        return;
    }
    for (int i = 1; i <= n; i++) {
        if(vis[i]) {
            continue;
        }
        vis[i] = true;
        per[dep] = i;
        dfs(dep + 1);
        vis[i] = false;
}

如果想要输出 n 个数字的 k 排列,我们可以在之前代码上进行一些较小的修改。当我们选取到 k 个数字时就应该停止继续搜索枚举的过程。

cpp 复制代码
int n;
int per[N];
bool vis[N];
void dfs (int dep) {
    if (dep == k) {
        for (int i = 0; i < k; i++) {
            cout << per[i] << " ";
        }
        cout << endl;
        return;
    }
    
    for (int i = 1; i <= n; i++) {
        if(vis[i]) {
            continue;
        }
        vis[i] = true;
        per[dep] = i;
        dfs(dep + 1);
        vis[i] = false;
    }
}
相关推荐
8Qi85 分钟前
LeetCode 76. 最小覆盖子串(Minimum Window Substring)
数据结构·算法·leetcode·滑动窗口·哈希表
weixin_BYSJ19877 分钟前
springboot旅游管理系统04470(附源码+开发文档+部署教程)
java·spring boot·python·算法·django·flask·旅游
Bingorl8 分钟前
机器学习之朴素贝叶斯算法
人工智能·算法·机器学习
8Qi89 分钟前
LeetCode 209. 长度最小的子数组(Minimum Size Subarray Sum)
java·算法·leetcode·双指针·滑动窗口
狮子座明仔32 分钟前
DeCoRL:把推理链拆成“乐团合奏“——AAAI 2026 一篇把 RLHF 推到 32B 打 GPT-4o 的工作
人工智能·深度学习·算法
QiLinkOS34 分钟前
合肥气链科技有限公司创办与未来技术应用
c语言·数据结构·c++·人工智能·单片机·嵌入式硬件·算法
妄想出头的工业炼药师39 分钟前
追踪定位大模型
算法·开源
Solis程序员41 分钟前
TreeMap 核心原理与实战
java·数据结构·算法
zzzsde1 小时前
【Linux】线程同步和互斥(5):线程池的实现&&线程安全
linux·运维·服务器·开发语言·算法·安全
weixin_468466851 小时前
机器学习数据预处理新手实战指南
人工智能·python·算法·机器学习·编程·数据预处理