栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

剑指 Offer 38. 字符串的排列(回溯法)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

剑指 Offer 38. 字符串的排列(回溯法)

文章目录
    • 方法一
    • 方法二

方法一

class Solution {
public:
    string str;
    int len;
    vector ans;

    void func(int i){
        if(i == len){
            ans.push_back(str);
            return;
        }
        for(int j = i; j < len; j++){
            swap(str[j], str[i]);
            func(i + 1);
            swap(str[j], str[i]);
        }
    }

    vector permutation(string s) {
        // 回溯法
        str = s;
        len = s.size();
        func(0);
        return ans;
    }
};

想着采用排列树的方式解决,可这种方式只能处理字符不重复的字符串


我们这里用set去重,然后构造vector返回即可通过所有测试用例

方法二

我们接下来用穷举法解决不可重复问题

完整的解空间树如下(continue):

注意:从完整的解空间树中可以看到,画红圈的分支不是没有生成,而是由于跳过了重复的字符,所以无法到达最后一层

完整的解空间树如下(break):

我们避免重复的方法是:最终的排列结果中,保证重复字符的相对位置不变,这就达到了去重的目的

比如: a 1 a 2 a 3 a_1a_2a_3 a1​a2​a3​、 a 1 a 3 a 2 a_1a_3a_2 a1​a3​a2​、 a 2 a 1 a 3 a_2a_1a_3 a2​a1​a3​、 a 2 a 3 a 1 a_2a_3a_1 a2​a3​a1​、 a 3 a 1 a 2 a_3a_1a_2 a3​a1​a2​、 a 3 a 2 a 1 a_3a_2a_1 a3​a2​a1​,我们只保留最后一个

  • 准备一个string类型的变量tmp,记录当前选择了哪些字符,深入到解空间树最后一层时,tmp就和原始字符串一样长,可以用ans保存
  • 由于需要判断字符是否选择过,还需要一个used数组,判断非第一个重复字符前面的字符是否用过,用过则break,没用过则继续深入下一层
class Solution {
public:
    string str;
    string tmp;
    int len;
    vector used;
    vector ans;

    void func(int i){
        if(i == len){
            ans.push_back(tmp);
        }else{
            for(int j = 0; j < len; j++){
                // 深入一层时,都会遍历所有的字符,如果当前字符被用过,就不会做任何操作
                if(used[j]){
                    continue;
                }
                // 当前字符没用过,但是和前面用过的字符相同(由于排序了,相同的字符一定相邻)
                if(j > 0 && used[j-1] && str[j] == str[j-1]){
                    // 当前字符和前面的相等,且前面的已经用过,则不用当前字符,不在继续向下深入
                    // 也可写成continue
                    break;
                }
                used[j] = true;
                tmp.push_back(str[j]);
                func(i + 1);
                tmp.pop_back();
                used[j] = false;
            }
        }
    }

    vector permutation(string s) {
        // 回溯法
        sort(s.begin(), s.end());
        str = s;
        len = s.size();
        used.assign(len, false);
        func(0);
        return ans;
    }
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/976418.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号