力扣 面试题38. 字符串的排列 dfs+回溯

https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/
在这里插入图片描述

思路:dfsdfs+回溯,注意判重即可。
自己实现的究极暴力版本:

class Solution {
public:
    bool vis[8]={0};
    int pos[8]={0};
    vector<string> ans;
    void dfs(int idx,string &s)
    {
        int siz=s.size();
        if(idx==siz)
        {
            string res(idx,' ');
            for(int i=0;i<idx;i++)
                res[i]=s[pos[i]];
            ans.push_back(res);
            return;
        }
        for(int i=0;i<siz;i++)
        {
            if(vis[i])
                continue;
            vis[i]=1;
            pos[idx]=i;
            dfs(idx+1,s);
            vis[i]=0;
        }
    }

    vector<string> permutation(string s) {
        sort(s.begin(),s.end());
        if(!s.size())
            return ans;
        dfs(0,s);
        sort(ans.begin(),ans.end());
        ans.erase(unique(ans.begin(),ans.end()),ans.end());
        return ans;
    }
};

然而这种去重方式太暴力了,我们优化一下,显然在一次深搜过程中,任意一个字符在位置ii只能出现11次,否则一定会产生重复的情况。这种方式的深搜返回的结果一定是有序的。

class Solution {
public:
    bool vis[8]={0};
    int pos[8]={0};
    vector<string> ans;
    void dfs(int idx,string &s)
    {
        int siz=s.size();
        if(idx==siz)
        {
            string res(idx,' ');
            for(int i=0;i<idx;i++)
                res[i]=s[pos[i]];
            ans.push_back(res);
            return;
        }
        bool check[26]={0};
        for(int i=0;i<siz;i++)
        {
            if(vis[i]||check[s[i]-'a'])
                continue;
            check[s[i]-'a']=1;
            vis[i]=1;
            pos[idx]=i;
            dfs(idx+1,s);
            vis[i]=0;
        }
    }

    vector<string> permutation(string s) {
        sort(s.begin(),s.end());
        if(!s.size())
            return ans;
        dfs(0,s);
        return ans;
    }
};

因为返回的顺序是任意的,所以我们可以选择交换元素的方式来实现,这种方式结果并不一定有序

class Solution {
public:
    vector<string> ans;
    void dfs(int idx,string &s)
    {
        int siz=s.size();
        if(idx==siz)
        {
            ans.push_back(s);
            return;
        }
        bool vis[26]={0};
        for(int i=idx;i<siz;i++)
        {
            if(vis[s[i]-'a'])
                continue;
            vis[s[i]-'a']=1;
            swap(s[idx],s[i]);
            dfs(idx+1,s);
            swap(s[idx],s[i]);
        }
    }

    vector<string> permutation(string s) {
        sort(s.begin(),s.end());
        if(!s.size())
            return ans;
        dfs(0,s);
        return ans;
    }
};

利用库函数,快的飞起,而且用这种方式计算出的结果是有序的。

class Solution {
public:
    vector<string> permutation(string s) {
        sort(s.begin(),s.end());
        vector<string> ans;
        do
        {
            ans.push_back(s);
        }while(next_permutation(s.begin(),s.end()));
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章