其他分享
首页 > 其他分享> > 剑指offer(38)

剑指offer(38)

作者:互联网

剑指offer(38)

剑指 Offer 38. 字符串的排列

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

示例:

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

限制:

1 <= s 的长度 <= 8

利用回溯方法去解决这个问题

对于重复字符的问题,要学会排序string后去处理

class Solution {
public:
    vector<string> rec;
    vector<int> vis;
    //回溯法
    void backtrack(const string& s, int i, int n, string& perm) {
        if (i == n) {
            rec.push_back(perm);
            return;
        }
        //每次遍历string s,选择未被使用过的
        for (int j = 0; j < n; j++) {
            //如果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.size();
        //vis是判别数组 判断这个位置的字符是否被使用
        vis.resize(n);
        //排序,这样可以去处理重复字符的问题
        sort(s.begin(), s.end());
        string perm;
        //回溯
        backtrack(s, 0, n, perm);
        return rec;
    }
};

标签:字符,38,string,offer,int,backtrack,perm,vis
来源: https://www.cnblogs.com/BailanZ/p/16217629.html