[算法练习-剑指offer]题27.字符串的排列(Java)(存疑)

题目

题号:27
题目名:字符串的排列

编程语言

Java

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字

符串abc,acb,bac,bca,cab和cba。

输入描述:

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

初次思路

https://leetcode-cn.com/problems/permutations-ii/与力扣47题全排列 II类似

要点是有重复,但是要输出所有不重复的组合全排列

是非常经典的dfs问题,但是要遍历的过程中将重复的去掉

我这里考虑使用一个数组去记录使用过的字母,如果使用过就为true否则为false

因为已经排序过,所以一样的字母会排在一起,然后因为是从前往后遍历,所以需要记录第一次重复的字符,如果字符重复,就不进行遍历

这里不能使用前后比较去重!!!

解题代码

public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> strs = new ArrayList<>();
        //非空校验
        if (str == null || str.length() == 0) return strs;
        char[] chars = str.toCharArray();//将字符串咋换成数组
        Arrays.sort(chars);//排序
        boolean[] isUsed = new boolean[str.length()];//看看哪些用过
        StringBuilder sb = new StringBuilder();//存放使用过的字符
        //dfs遍历
        dfs(strs, sb, chars, isUsed);
        return strs;
    }

    private void dfs(ArrayList<String> strs, StringBuilder sb, char[] chars, boolean[] isUsed) {
        //如果添加完毕
        if (sb.length() == chars.length) {
            strs.add(sb.toString());
            return;
        }
        //定义一个之指针记录上次使用的字母
        char lastChar = ' ';
        for (int i = 0; i < chars.length; i++) {
            //如果该字母没有被使用过,加入当前位置
            if (lastChar!=chars[i]&&!isUsed[i]) {
                sb.append(chars[i]);//如果该字母没有被使用过,加入当前位置
                isUsed[i] = true;
                dfs(strs, sb, chars, isUsed);
                lastChar = chars[i];
                sb.deleteCharAt(sb.length() - 1);//剪枝
                isUsed[i] = false;
            }
        }

    }
}

算法练习代码我都开源在码云上,有需要的朋友可以看看

https://gitee.com/xiaoxiaoyuworkspace/offeralgorithm

猜你喜欢

转载自blog.csdn.net/qq_41522089/article/details/107722601