前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode-面试题38-字符串的排列

LeetCode-面试题38-字符串的排列

作者头像
benym
发布2022-07-14 15:19:41
2000
发布2022-07-14 15:19:41
举报
文章被收录于专栏:后端知识体系后端知识体系

# LeetCode-面试题38-字符串的排列

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

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

示例:

代码语言:javascript
复制
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]

限制:

1 <= s 的长度 <= 8

# 解题思路

方法1:DFS全排列+剪枝

基本原理通过字符交换的方式,先固定第1位,再固定第2位,一直到固定第n位。

比如固定a,找剩下bc的可能排列,再固定b,找剩下c的可能排列。

之后固定b,找ac的可能排列....直到所有的组合都被找到

特例处理:当初始的字符串有重复的字符时,如aab,需要保证字符只在此为固定一次,即遇到重复的字符时不进行交换直接跳过,即剪枝

方法2:DFS+回溯

全排列问题详解见该文 (opens new window)

路径从空开始构建,当DFS深度达到了字符串长度时则添加进去,之后开始回溯,将访问过的状态复原,path弹出

# Java代码

代码语言:javascript
复制
class Solution {
    List<String> res = new LinkedList<>();
    public String[] permutation(String s) {
        if(s==null||s.length()==0) return new String[0];
        char[] c = s.toCharArray(); 
        StringHelper(c,0);
        return res.toArray(new String[res.size()]);
    }

    public void StringHelper(char[] c,int start){
        if(start==c.length-1){
            res.add(String.valueOf(c)); // 添加排列
            return;
        }
        HashSet<Character> set = new HashSet<>();
        for(int i=start;i<c.length;i++){
            if(set.contains(c[i])) continue; // 剪枝重复的
            set.add(c[i]);
            // 交换,将c[i]固定在start位置,比如abc,此时固定a
            char temp = c[i];
            c[i] = c[start];
            c[start] = temp;
            // 递归start+1位置,比如abc,此时进入bc的固定再交换,递归
            StringHelper(c,start+1);
            // 恢复交换
            temp = c[i];
            c[i] = c[start];
            c[start] = temp;
        }
    }
}

# Python代码

代码语言:javascript
复制
class Solution:
    def permutation(self, s: str) -> List[str]:
        def dfs(s, size, depth, visited, path, res):
            if depth == size: # 路径达到长度了,进行添加
                res.append("".join(path[:]))
                return

            for i in range(size):
                if not visited[i]:
                    # 如果当前节点和前一个节点相同,且他的前一个节点已经被遍历,则跳过
                    if i>0 and s[i]==s[i-1] and not visited[i-1]:continue
                    visited[i] = True # 访问过了
                    path.append(s[i]) # 添加进路径
                    dfs(s, size, depth + 1, visited, path, res) # 开启DFS
                    visited[i] = False # 回溯,状态还原
                    path.pop() # 路径还原
                
        s = list(sorted(s)) # 考虑重复问题,先进行排序
        size = len(s)
        if size == 0:
            return []
        res = []
        path = []
        visited = [False for _ in range(size)]
        dfs(s, size, 0, visited, path, res)
        return res

# Java代码2

代码语言:javascript
复制
class Solution {
    public String[] permutation(String s) {
        int len = s.length();
        Set<String> result = new HashSet<>();
        boolean[] visited = new boolean[len];
        char[] charStr = s.toCharArray();
        dfs("",charStr,result,len,visited);
        return result.toArray(new String[0]);
    }

    public void dfs(String s,char[] charStr,Set<String> result,int len,boolean[] visited){
        if(s.length()==len){
            result.add(s);
            return;
        }
        for(int i =0;i<len;i++){
            if(visited[i]){
                continue;
            }
            if(i>0&&charStr[i]==charStr[i-1]&&!visited[i-1]){
                continue;
            }
            visited[i] = true;
            dfs(s+String.valueOf(charStr[i]),charStr,result,len,visited);
            visited[i] = false;
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # LeetCode-面试题38-字符串的排列
    • # 解题思路
      • # Java代码
        • # Python代码
          • # Java代码2
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档