LeetCode面试题 08.08. 有重复字符串的排列组合(DFS)

博客探讨了如何解决有重复元素的字符串排列问题。提供了两种解决方案:一种针对重复元素进行了优化,通过排序和深度优先搜索(DFS)避免重复;另一种是通用的暴力求解方法,使用DFS遍历所有可能的排列。这两种方法都确保了所有元素在每个位置上出现一次。
摘要由CSDN通过智能技术生成

剑指 Offer II 084. 含有重复元素集合的全排列 

面试题 08.08. 有重复字符串的排列组合

                            

解题思路:

1.对于给定字符串的长度,使得每一种元素在字符串每一个位置都出现一遍。

                

2. 

                                                                 

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/7p8L0Z/solution/han-you-zhong-fu-yuan-su-ji-he-de-quan-p-qxwv/

来源:力扣(LeetCode)

                                

 代码1:    对于具有相同字符进行优化。

class Solution 
{ 
public:
    vector<string> permutation(string S) 
    {
        int sz = S.size();
        vector<string> ans;
        sort(S.begin(), S.end()); //使相同的元素在一起

        vector<int> visited(sz,0);

        string path=S;
        DFS(ans,0, visited, S, path);

        return ans;
    }

    void DFS( vector<string>& ans,int n, vector<int> &visited, const string &s, string &path) 
    {
        if (n == visited.size()) //返回条件,string中字符个数已经够了
        {
            ans.push_back(path);
            return;
        }

        for (int i = 0; i < s.size(); ++i) 
        {
            if (visited[i]) 
            continue;
            
            //只使用第一个重复的元素
            if (i > 0 && s[i] == s[i - 1] && !visited[i - 1]) 
            continue;

            visited[i] = 1;//标记已访问
            path[n] = s[i];
            DFS(ans, n + 1, visited, s, path); //使每一种元素在每个位置都出现一遍
            visited[i] = 0; //回溯
        }
    }
};

                                         

     代码2: 通用解法,暴力求解          

class Solution {
public:
    set<string> store; //用于存储结果
    vector<string> ret;

    void dfs(string& s, string& cur, vector<bool>& used){
        if(cur.size() == s.size())
        {
            store.insert(cur);
            return;
        }

        for(int i = 0; i < s.size(); ++i)
        {
            if(used[i]) //这个字符被使用过了,寻找未被使用的
            continue;

            cur += s[i];
            used[i] = true;
            dfs(s, cur, used);
            used[i] = false;
            cur.pop_back();
        }
    }

    vector<string> permutation(string s) 
    {
        string cur = "";
        vector<bool> used(s.size(), false);//标记字符是否被使用
        dfs(s, cur, used);

        for(auto& ele : store) 
         ret.push_back(ele);

        return ret;
    }  
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值