LeetCode 面试题 08.08. 有重复字符串的排列组合

文章目录

一、题目

  有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。

示例1:

输入:S = "qqe"

输出:"eqq","qeq","qqe"

示例2:

输入:S = "ab"

输出:"ab", "ba"

提示:

  • 字符都是英文字母。
  • 字符串长度在1, 9之间。

  点击此处跳转题目

二、C# 题解

  同题目 LeetCode 面试题 08.07. 无重复字符串的排列组合,进行剪枝:

  1. 元素 Si 与 Sn 相同时,舍去;
  2. 所得为新结果时,才纳入 ans。

  步骤 1 剪枝不完全,所以还需加上步骤 2。

csharp 复制代码
public class Solution {
    public string[] Permutation(string S) {
        List<string> ans = new List<string>();
        Partition(ans, new StringBuilder(S), 0);
        return ans.ToArray();
    }

    public void Partition(List<string> ans, StringBuilder sb, int n) {
        if (n == sb.Length) {
            ans.Add(sb.ToString());
            return;
        }
        HashSet<char> hs = new HashSet<char>();
        for (int i = n; i < sb.Length; i++) {
            if (hs.Contains(sb[i])) continue;
            hs.Add(sb[i]);
            (sb[i], sb[n]) = (sb[n], sb[i]);
            Partition(ans, sb, n + 1);
            (sb[i], sb[n]) = (sb[n], sb[i]);
        }
    }
}
  • 时间:140 ms,击败 71.43% 使用 C# 的用户
  • 内存:46.7 MB,击败 92.86% 使用 C# 的用户

  另一种剪枝方式,用一个 Set 集合存放已经交换过的重复元素,即不让当前 Sn 与已经交换过的字母再进行交换:

csharp 复制代码
public class Solution {
    public string[] Permutation(string S) {
        List<string> ans = new List<string>();
        Partition(ans, new StringBuilder(S), 0);
        return ans.ToArray();
    }

    public void Partition(List<string> ans, StringBuilder sb, int n) {
        if (n == sb.Length) { // 递归出口
            ans.Add(sb.ToString());
            return;
        }
        HashSet<char> hs = new HashSet<char>(); // 记录已交换过的元素
        for (int i = n; i < sb.Length; i++) {
            if (hs.Contains(sb[i])) continue;   // 该元素已被交换过,则跳过
            hs.Add(sb[i]);                      // 添加记录
            (sb[i], sb[n]) = (sb[n], sb[i]);
            Partition(ans, sb, n + 1);
            (sb[i], sb[n]) = (sb[n], sb[i]);
        }
    }
}
  • 时间:128 ms,击败 100.00% 使用 C# 的用户
  • 内存:46.38 MB,击败 78.57% 使用 C# 的用户
相关推荐
旖-旎33 分钟前
《LeetCode 53 最大子数组和 || LeetCode 918 环形子数组的最大和》
c++·算法·leetcode·动态规划
变量未定义~36 分钟前
单调栈+倍增思想 皇家守卫【算法赛】、单调队列 附近最小
算法
QN1幻化引擎38 分钟前
给 AI 做一次「意识体检」——基于 QN1 幻化引擎的灵鉴意识识别框架与 DalinX V5 实测
大数据·数据结构·人工智能·算法·架构
拂拉氏1 小时前
【知识讲解】 AVL树从基本成员的介绍到核心接口的实现(插入、判断、删除等等)
数据结构·算法·avl树
xiaoshuaishuai81 小时前
C# AI实现PR处理、单元测试
开发语言·c#·log4j
LONGZHIQIN1 小时前
C#基础复习笔记
开发语言·笔记·c#
可靠的仙人掌2 小时前
SAC(Soft Actor-Critic)算法底座
开发语言·算法·php
海石3 小时前
单调栈复健,顺便,牺牲一下吧,空间复杂度!一切献给AC
算法·leetcode
海石3 小时前
JS击败94%,Hard题想不到动态规划,那就用数组和栈试试
算法·leetcode
品尚公益团队4 小时前
C#在asp.net网页开发中的带cookie登录实现
前端·c#·asp.net