无重复字符串的排列组合

本文介绍了如何使用递归和C++ STL中的next_permutation函数计算字符串的所有无重复字符的排列组合。通过示例代码详细解析了递归方法和next_permutation函数的应用,并探讨了不同方法的优缺点。同时,提出了在解决全排列问题时的思考和技巧,包括如何避免使用额外的visited数组以及如何利用回溯优化解决方案。
摘要由CSDN通过智能技术生成
面试题 08.07. 无重复字符串的排列组合

无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。

示例1:

 输入:S = "qwe"
 输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"]

示例2:

 输入:S = "ab"
 输出:["ab", "ba"]

提示:

  1. 字符都是英文字母。
  2. 字符串长度在[1, 9]之间
个人所写

这里看不懂就不要看了,==>写的太麻烦,时间一久我也看不懂;

class Solution {
public:
    vector<string> permutation(string S) {
vector<string>ans;
int temp[S.size()];
memset(temp,0,sizeof temp);
find(ans,"",S.size(), S,temp);
return ans;
    }
   void  find(vector<string>&ans,string s,int n,string all,int temp[])//函数参数有点多;
    {
        if(n==0)
        {
            ans.push_back(s);return ;
        }
         for(int i=0;i<all.size();i++)
        {
if(temp[i]!=1){
    temp[i]=1;find(ans,s+all[i],n-1,all,temp);
    temp[i]=0;(在此处,一定要改回来.否则由于temp数组在函数中的全局,只会产生一个/)
}
        }

    }
};

这是第一次凭自己的本事做出来的这种递归题,所以想记录下来.当然代码有些麻烦.


方法技巧

还有一个专门的函数:next_permutation()

按照STL文档的描述,next_permutation函数将按字母表顺序生成给定序列的下一个较大的排列,直到整个序列为降序为止。prev_permutation函数与之相反,是生成给定序列的上一个较小的排列。

这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件<algorithm>

有上述可知,对于next_permutation而言,必须先进行从小到大的排序,否则只要数组不是从小到大,那么就得出的结果一定不是正确的答案

看代码:

int a[];
sort(a,a+n);//此处是一定需要的,如上述的描述;如果不进行排序,那么结果就是:从数组中当前的字典序开始依次增大直至到最大字典序。
do
{
}
while(next_permutation(a,a+n));
//这是一个标准的模板;

如果直接用while(next_permutation(a,a+n)){},

因为在一开始判断的时候,就已经生成了一个a的全序列,所以少的那一个就是字典序最小的那一个;

//如果按字母表顺序还含有比较大的排序,那么next_permutation()就会返回true;

一种比较简洁的方法
image-20210221152755331
class Solution {
private:
    vector<string> res;
    void dfs(string &s, int left){
        if(left==s.size()) res.emplace_back(s);
        for(int i=left; i<s.size(); ++i){
            swap(s[i], s[left]); //交换位置
            dfs(s, left + 1);//递归
            swap(s[i], s[left]);//回溯
        }
    }
public:
    vector<string> permutation(string S) {
        res.clear();
        dfs(S, 0);
        return res;
    }
};

这道题也同样说明,对于一个dfs的题目,大可以不必死板的用visited数组来表示是否被访问,还可以用swap等其他的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值