方法:递归+回溯

和前面有重复项数字的全排列方法一样,即使这里是字符串但是排序后还是方便将相同的字母放在一块便于判断去重。其他都和前面一样,就是排序需要将字符串转为字符数组,还有字符串不能直接增删所以采用StringBuffer作为临时数组,可以增删字符。

import java.util.*;
public class Solution {
    public void dfs(ArrayList<String> res,char[] str,StringBuffer temp,boolean[] vis){
        if(temp.length()==str.length){
            res.add(new String(temp));
            return;
        }
        for(int i=0;i<str.length;i++){
            if(vis[i]){
                continue;//被遍历过则跳过
            }
            if(i>0&&str[i-1]==str[i]&&!vis[i-1]){
                continue;//若和前一个并且是未被访问的字母相同则跳过
            }
            vis[i]=true;
            temp.append(str[i]);
            dfs(res,str,temp,vis);
            //回溯
            vis[i]=false;
            temp.deleteCharAt(temp.length()-1);//去掉最后加入的字母
        }
    }
    public ArrayList<String> Permutation (String str) {
        ArrayList<String> res = new ArrayList<String>();
        if(str==null||str.length()==0){
            return res;  //返回空数组
        }
        char[] charStr = str.toCharArray(); //转为字符数组,方便排序
        Arrays.sort(charStr);
        //标记数组
        boolean[] vis = new boolean[str.length()];
        //初始化
        Arrays.fill(vis,false);
        //建立临时数组,存储当前的排列情况
        StringBuffer temp = new StringBuffer();
        //递归
        dfs(res,charStr,temp,vis);

        return res;
    }
}