【经典算法】全排列问题(暴搜枚举)

超级经典的回溯算法,必须会

题目简述

给定一个整数n,将数字1~n排成一排,按照字典序将所有的排列输出。
输入格式
共一行,包含一个整数n。
输出格式
按字典序输出所有排列方案,每个方案占一行。
数据范围

1≤n≤9

输入样例:

3

输出样例:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

暴力枚举

在这里插入图片描述

上图是递归树。我们要枚举,递归都可以画一棵树。当我们到最后一层时候,即该排列所有位都枚举完,填上数字了,就输出并返回。否则我们要枚举该排列的枚举的位上应该填什么数。
经典的回溯算法,暴力枚举。 时间复杂度O(N!),空间复杂度O(N),用一个数组来存储每次枚举的状态

核心代码

#include <iostream>
using namespace std;

const int N = 10 ;

int n;
bool st[N];//记录该点是否已经用过了,用于剪枝
int path[N];

void dfs(int u){
    if (u == n){
        //到最后一层,所有位都填好了
        for (int i = 0 ; i < n ; i ++) cout << path[i] << " ";
        cout << endl;
        return ;
    }
    //还没到最后一层,枚举该位置能放哪些数
    for (int i = 1 ; i <= n ; i ++){
        //剪枝
        if (st[i] == false){
            path[u] = i;
            st[i] = true;
            dfs(u + 1);//递归下一层
            st[i] = false;//回溯的恢复
        }
    }
    
}


int main(){
    cin >> n;
    //暴力枚举
    dfs(0);
    
    return 0;
}
  • 2
    点赞
  • 5
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

Miiiiiiiiiii

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值