题解 | 字符串的排列

字符串的排列

https://www.nowcoder.com/practice/fe6b651b66ae47d7acce78ffdd9a96c7?tpId=295&tqId=23291&sourceUrl=%2Fexam%2Foj%3FquestionJobId%3D10%26subTabName%3Donline_coding_page

class Solution {
  public:
    vector<string> Permutation(string str) {
        vector<string> result;
        if (str.empty()) return result;

        // 对字符串排序,便于去重
        sort(str.begin(), str.end());
        vector<bool> used(str.size(), false);
        string path;
        backtrack(str, used, path, result);
        return result;
    }

  private:
    void backtrack(const string& str, vector<bool>& used, string& path,
                   vector<string>& result) {
        // 终止条件:当前路径长度等于原字符串长度
        if (path.length() == str.length()) {
            result.push_back(path);
            return;
        }

        for (int i = 0; i < str.length(); i++) {
            // 跳过已使用的字符
            if (used[i]) {
                continue;
            }

            // 去重:如果当前字符与前一个字符相同,且前一个字符未被使用,则跳过
            // 这样可以避免生成重复的排列
            if (i > 0 && str[i] == str[i - 1] && !used[i - 1]) {
                continue;
            }

            // 做出选择
            used[i] = true;
            path.push_back(str[i]);

            // 递归
            backtrack(str, used, path, result);

            // 撤销选择
            path.pop_back();
            used[i] = false;
        }
    }
};

本题与有重复数字全排列的相似性
两者确实非常相似:
相同点:
都使用回溯算法框架
都需要处理重复元素/字符的问题
都使用排序+跳过重复元素的策略来去重
都使用标记数组来记录已使用的元素

不同点:
输入类型不同:一个是数字数组,一个是字符串
输出格式不同:一个返回数字列表的列表,一个返回字符串列表

递归/回溯 文章被收录于专栏

递归 (Recursion) 递归是函数调用自身的一种编程技巧,包含两个关键部分: 基线条件:递归终止的条件 递归条件:函数调用自身的条件 回溯 (Backtracking) 基本概念 回溯是一种通过&quot;试错&quot;来寻找问题解的算法,当发现当前路径不能得到有效解时,会退回上一步尝试其他可能性。 核心思想:深度优先搜索 + 状态重置

全部评论

相关推荐

Cl_Wg:看牛客匿名贴容易抑郁,白菜就是我的天花板
点赞 评论 收藏
分享
2025-12-13 14:51
已编辑
井冈山大学 算法工程师
龙虾x:算法比你强的没有你美,比你美的…..算了已经没有比你美的了
工作两年想退休了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务