ソードフィンガーオファー38.ストリングの配置(C ++)バックトラッキング方法

文字列を入力し、文字列内の文字のすべての順列を出力します。
この文字列配列は任意の順序で返すことができますが、重複する要素を含めることはできません。

例:

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

制限:
1 <= sの長さ<= 8

問題解決のアイデア:

**これと同様:** https://blog.csdn.net/qq_30457077/article/details/114375222
ここに画像の説明を挿入します
ここに画像の説明を挿入します
繰り返し配置スキームとプルーニング:
文字列に繰り返し文字がある場合、配置スキームにも繰り返し配置スキームがあります。繰り返しスキームを排除するために、特定の文字を固定する場合、「各文字がこの位置に1回だけ固定される」こと、つまり繰り返し文字が検出されたときにそれらが交換されて直接スキップされないようにする必要があります。DFSの観点から、この操作は「プルーニング」と呼ばれます。

ここに画像の説明を挿入します
ここに画像の説明を挿入します

class Solution {
    
    
public:
    vector<string> permutation(string s) {
    
    
        dfs(s, 0);
        return res;
    }
private:
    vector<string> res;
    void dfs(string s, int x) {
    
    
        if(x == s.size() - 1) {
    
    
            res.push_back(s);                       // 添加排列方案
            return;
        }
        set<int> st;//首先vector属于顺序容器,其元素与存储位置与操作操作有关;
        //set属于关联容器,其元素相当于键值。set能够保证它里面所有的元素都是不重复的(multiset除外)。
        //因此,此处用set
        for(int i = x; i < s.size(); i++) {
    
    
            if(st.find(s[i]) != st.end()) continue; // 若s[i]存在于st,重复,因此剪枝
            st.insert(s[i]);//将 c[i] 加入 Set​ ,以便之后遇到重复字符时剪枝;
            swap(s[i], s[x]);                       // 交换,将 s[i] 固定在第 x 位;因为此处已经交换
            //,所以x == s.size() - 1时,执行res加入新元素
            /* if(x == s.size() - 1) {
            res.push_back(s);                       // 添加排列方案
            return;
        }
            */
            dfs(s, x + 1);                          // 开启固定第 x + 1 位字符
            swap(s[i], s[x]);                       // 恢复交换
        }
    }
};

複雑さの分析:

ここに画像の説明を挿入します

著者:jyd
リンク:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/solution/mian-shi-ti-38-zi-fu-chuan-de-pai -lie-hui-su-fa-by /
出典:LeetCode(LeetCode)
著作権は作者に帰属します。商用の転載の場合は、著者に連絡して許可を求め、非商用の転載の場合は、出典を示してください。

おすすめ

転載: blog.csdn.net/qq_30457077/article/details/114982754