算法分析——Perm算法

目录


前言

Perm算法是一种解决全排列问题的思想,它是递归的一个实例。


一、递归算法

一个直接或间接地调用自身的算法成为递归算法。递归算法有两个基本组成元素:递归方程(一个使用函数自身给出定义的函数)和边界条件

 在合并排序和快速排序一问中,我总结了分治策略在大规模问题中的引用。递归算法与分治策略都是将分体划分后重复调用并求解的过程,区别在于递归算法是已知问题的结果和边界条件;分治法是已知问题的中间过程,再逐步将问题划分并求解。

二、Perm算法

1.全排列问题

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

全排列数:f(n)=n! (0!=1)

使用Perm算法解决全排列问题的代码如下:

template <class Type>
void Perm(Type list[],int k,int m){
    if(k==m){
        for(int i=0;i<=m;i++)
            cout<<list[i];
        cout<<endl;
    }
    else
    for(int i=k;i<=m;i++){
        Swap(list[k],list[i]);
        Perm(list,k+1,m);
        Swap(list[k],list[i]);
    }
}

template <class Type>
inline void Swap(Type &a,Type &b){
    Type temp=a;
    a=b;
    b=temp;
}

在排列一个长度为n的数组时,依次让每个元素成为数组的“头部”,对其他n-1个元素进行全排列,待排元素数为1时,直接输出结果。为了方便,设置参数k、m,令它们分别指向待排数组首尾,通过增减k、m移动指针。需要注意的是,每一次完成交换list[p]和list[i]的排序后,都需要把它们再次交换到原位后再进行下一次排列。

Perm算法时间复杂度为O(n!),在实际问题中,根据条件的不同全排列问题还有许多优化解法。

2.全排列问题的其他解法

(1)Johnson-Trotter算法

Johnson-Trotter算法并未提高代码运行的时间复杂度,但是它不需要将多余的遍历信息压栈,降低了空间复杂度。

Johnson-Trotter算法icon-default.png?t=N7T8http://【如何优雅地生成全排列——4分钟看懂【Johnson-Trotter全排列生成算法】】 https://www.bilibili.com/video/BV1XY411E7kz/?share_source=copy_web&vd_source=0cecc0fc0417017001dd525fe8051adb

(2)回溯算法解决全排列

leetcode相关例题的讲解非常清楚,附上链接以便后续学习。

回溯算法解决全排列_leetcodeicon-default.png?t=N7T8http://【46. 全排列 Permutations 【LeetCode 力扣官方题解】】 https://www.bilibili.com/video/BV1oa4y1v7Kz/?share_source=copy_web&vd_source=0cecc0fc0417017001dd525fe8051adb


总结

以上就是关于Perm算法解决全排列的所有内容。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值