剑指 Offer 38. 字符串的排列

Posted 是七喜呀!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 38. 字符串的排列相关的知识,希望对你有一定的参考价值。

字符串的排列


题目链接: 剑指 Offer 38. 字符串的排列

有关题目

输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:

输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
限制:

1 <= s 的长度 <= 8

题解

法一:回溯

思路:
将这个问题看作有 n 个排列成一行的空位,我们需要从左往右
依次填入题目给定的 n 个字符,每个字符只能使用一次。
使用穷举法从左往右,依次填入字符
class Solution {
public:
    //创建全局变量数组,减少回溯函数传参
    vector<string> rec;
    vector<int> vis;
    void backtrack(const string& s,int i,int n,string& perm)
    //s 获得全排列的源字符串 i 下一个待填入的空位是第 i 个空位
    //n  = s.length()   perm 当前排序
    {
        if (i == n)//递归终止条件
            {
                rec.push_back(perm);
                return;
            }
        else
        {
            for (int j = 0; j < n; j++)
            {
                //在递归函数中,我们限制每次填入的字符一定是这个字符所在重复字符集合中「从左往右第一个未被填入的字符」保证生成不重复序列的必要条件
                if ((vis[j] || (j > 0 && !vis[j - 1] && s[j - 1] == s[j])))
                    continue;
                vis[j] = true;//标记
                perm.push_back(s[j]);
                backtrack(s,i + 1,n,perm);
                perm.pop_back();//拿掉上一个函数,防止数据污染
                vis[j] = false;//使用完,拿掉标记
            }
        }

    }

    vector<string> permutation(string s) {
        int n = s.length();
        vis.resize(n);
        sort(s.begin(),s.end());//给字符串排序,保证生成不重复序列的必要条件
        string perm;//定义backtrack函数中的当前 排序
        backtrack(s,0,n,perm);//调用回溯函数
        return rec;
    }
};

在这里插入图片描述
法二:下一个排列

思路:
结合next_permutation()函数思想,避免分类讨论,找出的一定是避免重复的字符串,下图附next_permutation函数的排列顺序

在这里插入图片描述

class Solution {
public:
    bool nextPermutation(string& s)
    {
        int i = s.length() - 2;
        while(i >= 0 && s[i] >= s[i + 1])
            --i;
        if (i < 0)
            return false;
        int j = s.length() - 1;
        while(j >= 0 && s[i] >= s[j])
            --j;

        swap(s[i],s[j]);
        reverse(s.begin() + i + 1,s.end());
        return true;
    }
    vector<string> permutation(string s) {
        vector<string> ret;
        sort(s.begin(),s.end());
        do
        {
            ret.push_back(s);
        }while(nextPermutation(s));
        return ret;
    }
};

在这里插入图片描述

以上是关于剑指 Offer 38. 字符串的排列的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer 38. 字符串的排列

剑指OFFER----面试题38. 字符串的排列

LeetCode(剑指 Offer)- 38. 字符串的排列

LeetCode 字符串的排列全排列问题(剑指offer38)

剑指offer 面试38题

剑指 Offer 38. 字符串的排列