剑指offer 面试题38. 字符串的排列 【回溯】

https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/solution/c-dfs-mian-shi-ti-38-zi-fu-chuan-de-pai-lie-by-yue/

交换回溯

class Solution {
public:
    vector<string> result;
    vector<string> permutation(string s) {
        dfs(s, 0);
        return result;
    }
    void dfs(string& s, int pos) {
        if (pos >= s.size()) {
            result.push_back(s);
            return;
        }
        for (int i = pos; i < s.size(); ++i) {
        
        	/ 如果pos和i之间有字符等于s[i],则跳过。或者这里也可用set储存结果的方式代替
            if (judge(s, pos, i)) continue;   
            
            swap(s[pos], s[i]);
            dfs(s, pos+1);
            swap(s[pos], s[i]);
        }
    }

    bool judge(string& s, int start, int end) {
        for (int i = start; i < end; ++i) {
            if (s[i] == s[end]) return true;
        }
        return false;
    }
};

剪枝回溯

class Solution {
public:
    vector<string> res;
    void backtrack(string s,string track,vector<bool>& visit){
        if(track.size()==s.size()){
            res.push_back(track);
            return;
        }
        for(int i=0;i<s.size();i++){
            if(visit[i]) continue;
            if(i>0&&!visit[i-1]&&s[i-1]==s[i]) continue; / 为了这步去重,才在一开始排了序
            visit[i]=true;
            track.push_back(s[i]);
            backtrack(s,track,visit);
            track.pop_back();
            visit[i]=false;
        }
    }
    vector<string> permutation(string s) {
        if(s.empty()) return {};     
        sort(s.begin(), s.end());   
        vector<bool> visit(s.size(),false);
        string track;
        backtrack(s,track,visit);
        return res;
    }
};

C++删除string最后一个字符的几种方法

调试

配合图示应该能看懂了。
面试题38. 字符串的排列(回溯法,清晰图解)

class Solution {
public:
    vector<string> result;
    vector<string> permutation(string s) {
        dfs(s, 0);
        return result;
    }
    void dfs(string& s, int pos) {
        cout<<s<<" @1 "<<endl;
        if (pos >= s.size()) {
            result.push_back(s);
            return;
        }
        for (int i = pos; i < s.size(); ++i) {
            if (judge(s, pos, i)) continue;   // 如果pos和i之间有字符等于s[i],则跳过。
            swap(s[pos], s[i]);
            cout<<"pos="<<pos<<" "<<"i="<<i<<" "<<s<<" @2 "<<endl;
            dfs(s, pos+1);
            swap(s[pos], s[i]);
            cout<<s<<" @3 "<<endl;
        }
    }

    bool judge(string& s, int start, int end) {
        for (int i = start; i < end; ++i) {
            if (s[i] == s[end]) return true;
        }
        return false;
    }
};
abc @1 
pos=0 i=0 abc @2 
abc @1 
pos=1 i=1 abc @2 
abc @1 
pos=2 i=2 abc @2 
abc @1 
abc @3 
abc @3 
pos=1 i=2 acb @2 
acb @1 
pos=2 i=2 acb @2 
acb @1 
acb @3 
abc @3 
abc @3 
pos=0 i=1 bac @2 
bac @1 
pos=1 i=1 bac @2 
bac @1 
pos=2 i=2 bac @2 
bac @1 
bac @3 
bac @3 
pos=1 i=2 bca @2 
bca @1 
pos=2 i=2 bca @2 
bca @1 
bca @3 
bac @3 
abc @3 
pos=0 i=2 cba @2 
cba @1 
pos=1 i=1 cba @2 
cba @1 
pos=2 i=2 cba @2 
cba @1 
cba @3 
cba @3 
pos=1 i=2 cab @2 
cab @1 
pos=2 i=2 cab @2 
cab @1 
cab @3 
cba @3 
abc @3 

猜你喜欢

转载自blog.csdn.net/g534441921/article/details/105541435