全排列c++代码_字符串的排列

e070cb0995ac57cb0ff41cad2d6f3c5e.png

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入描述

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

解题思路及代码

这个题目可以简单地抽象为求一个字符串的全排列。

全排列通过什么方法可以较好的求出来呢?

我们可以采用递归的方法不断固定某个位置上的字符来完成。

比如求 "ABC" 的全排列:

9a83efa4082313d77b7419d14a3e79f5.png

接着我们思考一个问题:在固定某个位置上字符的时候,如何找到该位置上所有可能的情况?(比如对于 ABC 来说,我们要固定第一个位置上的字符,那么有 A、B、C 三种情况,接着我们在 A 固定于第一个位置上之后,再固定第二个位置上的字符,这时我们有 B、C 两种选择,其他的同理。)

我们可以通过交换来获得所有可能的情况。比如第一个位置上的字符,假如 A 和 A 交换,就相当于第一个位置上固定了 A;假如 A 和 B 交换,B来到第一个位置,就相当于第一个位置上固定了 B;假如 A 和 C 交换,C来到第一个位置,就相当于第一个位置上固定了 C。递归的过程中都是同理。

此外,因为可能有字符重复,我们得到的全排列自然也会有重复,那么我们可以用 set (集合)来去重,并且还可以达到按照字母顺序排序的目的。

代码如下:

class Solution {
public:
    void perm(int pos, string s, set<string> &ret) {
        if (pos+1 == s.length()) {
            ret.insert(s);
            return;
        }
        // for循环和swap的含义:对于“ABC”,
        // 第一次'A' 与 'A'交换,字符串为"ABC", pos为0, 相当于固定'A'
        // 第二次'A' 与 'B'交换,字符串为"BAC", pos为0, 相当于固定'B'
        // 第三次'A' 与 'C'交换,字符串为"CBA", pos为0, 相当于固定'C'
        for (int i = pos; i < s.length(); ++i) {
            swap(s[pos], s[i]);
            perm(pos+1, s, ret);
            swap(s[pos], s[i]);
            // 回溯的原因:比如第二次交换后是"BAC",需要回溯到"ABC"
            // 然后进行第三次交换,才能得到"CBA"
        }
    }
    vector<string> Permutation(string s) { 
        if (s.empty()) return {};
        set<string> ret;
        perm(0, s, ret);
        return vector<string>({ret.begin(), ret.end()});    //将集合中的字符串转成字符串数组
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值