全排列问题(三个衍生问题 )

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38851184/article/details/82942493

鄙人不才,遇见的全排列问题和其衍生问题一共三种:1、无重复元素全排列问题。2、有重复元素全排列问题。3、n皇后问题

一、无重复元素全排列问题。给定一个数n,求从1~n的全排列。

看到网上教程很多都在说可以划分为以下几种情况: 以1开头,2~n的全排列;以2开头,1和3~n的全排列;...;n开头,1~n-1的全排列。

这个方法很好理解,但不好想,也不好写。真正理解要建立在对递归真了解的基础之上。不太理解先别着急,我们来总体分析一下(手动滑稽):一个函数,姑且叫它f(n),这个函数里面有一个for循环,当循环里的数满足一定条件的时候,我们进行调用f(n),这样,就是在循环中调用递归函数。当进行f(n)的时候,系统就会调用栈,自动地将当前的数据保存在栈中,当递归返回时,就会执行f(n)的下一条语句。

好了,废话了这么多,也算是把鄙人对着这三个问题的理解写出来了。其实只要这个问题理解了,剩下的有重复元素排列问题和n皇后问题很轻易就能理解代码。但是要注意,重复元素排列在拍之前要确定该数是否在之前出现过,n皇后问题我们用数组下标表示列。

代码二:有重复元素排列问题:

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e4+110;
char ch[maxn];
int cnt[maxn] = {0};
int tmp[maxn] = {0};
char num[maxn];
bool nt(int beg,int to)
{
    for(int i=beg; i<to; i++)
    {
        if(ch[i] == ch[to])
            return false;
    }
    return true;
}
void f(int n,int m)
{
    if(n+1 == m)
    {
        for(int i=1; i<=n; i++)
        {
            cout<<num[i];
        }
        cout<<endl;
    }else
    {
        int x;
        for(int i=1; i<=n; i++)
        {
            x = (int)ch[i];
          //  cout<<"x="<<x<<endl;
            if(tmp[x]<cnt[x] && nt(1,i))    //如果出现次数少于等于该元素的个数并且该元素在前面没有出现过
            {
                tmp[x]++;
                num[m] = ch[i];
                f(n,m+1);
                tmp[x]--;
            }
        }
    }
}
int main()
{
    cout<<"请输入元素个数:"<<endl;
    
    int n,x;
    cin>>n;
    cout<<"请输入元素"<<endl;
    for(int i=1; i<=n; i++)
    {
        cin>>ch[i];
        x = (int)ch[i];
        cnt[x]++;
    }
    //对有重复的序列进行排序
    f(n,1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38851184/article/details/82942493