全排列的两种写法

这篇博客介绍了如何使用深度优先搜索(DFS)配合回溯算法来按字典序输出1到n的所有整数排列。给出了两种不同的C++实现方式,并分析了它们的时间复杂度和空间复杂度。第一种方法利用了递归和标志数组,第二种方法通过避免重复选择同一元素提高了效率。博主强调了基础知识的重要性,并以此反思学习过程。
摘要由CSDN通过智能技术生成

题目:

给定一个整数n,将数字1~n排成一排,将会有很多种排列方法。

现在,请你按照字典序将所有的排列方法输出。

输入格式
共一行,包含一个整数n。

输出格式
按字典序输出所有排列方案,每个方案占一行。

数据范围
1≤n≤7
输入样例:
3
输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

思路:

这是一道基础的dfs+回溯,一层一层递归

代码1:

#include<iostream>
using namespace std;

const int N = 10;

int n;
int path[N];
bool st[N];

void dfs(int cnt){
    if(cnt == n){
        for(int i = 0;i < n;i ++) printf("%d ", path[i]);
        puts("");
        return ;
    }
    
    for(int i = 1;i <= n;i ++){
        if(!st[i]){
            path[cnt] = i;
            st[i] = true;
            dfs(cnt + 1);
            st[i] = false;
        }
    }
}

int main(){
    
    cin >> n;
    
    dfs(0);
    return 0;
}

时间复杂度:

O(n!)           就是dfs递归的次数,第一次n,第二次n-1,第三次n-2。。。以此类推

空间复杂度:

O(logn)           即logH,H为递归树的高度,就是程序运行时,堆栈段创建的栈帧的个数,每一层对应一个栈帧(确切来说不是同一个,因为不是同时执行,是用了最下面一层的,退栈再加入新栈)


代码2:

#include<iostream>
using namespace std;

const int N = 1010;
int n, A[N];

void print_permutation(int cur){
	if(cur == n){
		for(int i = 0;i < n;i ++) printf("%d ", A[i]);
		printf("\n");
		return ;
	}else{
		for(int i = 1;i <= n;i ++){
			int ok = 1;
			
			for(int j = 0;j < cur;j ++) // 之前有过 就不能选了
				if(A[j] == i) ok = 0;
			if(ok){
					A[cur] = i;
					print_permutation(cur+1);
			}	
			
		}
	}
	
}


int main(){
	cin >> n;
	
	print_permutation(0);
	return 0;
}

这个时间复杂度要比上一个高一些,因为每次添加的时候,都需要遍历一下之前是否存在该元素。第一种写法可以说是拿空间换时间


反思:
基础不牢地动山摇,学算法是如此,考研亦是如此,学习即如此!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Rabbit Coder

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

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

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

打赏作者

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

抵扣说明:

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

余额充值