字符串的排列

题目

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

分析

先确定字符串中第i个位置上的字符,剩余的字符递归进行全排列。例如,确定第一个位置上的字符为a,那么继续求bc的全排列就可以找到所有以a开头的字符串;确定第一个位置上的字符为b,求ac的全排列;确定第一个位置上的字符为c,求ab的全排列。当第一个位置上的字符确定后,找剩余的字符的全排列又可以重新从第二个位置上确定元素,递归进行。

 因为每当确定了一个位置上的字符后,剩余字符需要传递下去进行递归操作,这里采用交换的方法来解决。将确定的字符与当前第 i个字符相交换,然后i+1-N-1依然是剩下的字符。 但是要注意,这样做改变了字符数组,必须进行完一次dfs过程后,将数组复原,便于确定i位置其他元素时,不会受到影响。简单来说,就是当找到以a开头的所有字符串后,要将参与递归的字符串恢复到abc的状态,以便a和b进行交换,查找以b开头的全排列。

如何去重(原来字符串中有重复的字符,例如:aabc)?只要每一层确定的字符不一样,那么便不会出现重复元素,换句话说,只要每一次递归枚举确定i元素时,不出现重复的即可,这可用set实现。

代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;

public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> list = new ArrayList<String>();
        int length = str.length();
        if (length == 0){
            return list;
        }
        char[] temp = str.toCharArray();
        slove(list,temp,0);
        Collections.sort(list);
        return list;
    }

    private void slove(ArrayList<String> list, char[] temp, int i) {
        if (i == temp.length){
            list.add(new String(temp));
            return;
        }
        HashSet<Character> set = new HashSet<Character>();
        for (int j = i; j < temp.length; j++) {
            if (!set.contains(temp[j])){
                set.add(temp[j]);
                //交换
                swap(temp,i,j);
                slove(list, temp, i + 1);
                swap(temp,i,j);
            }
        }
    }

    private void swap(char[] temp, int i, int j) {
        char c = temp[i];
        temp[i] = temp[j];
        temp[j] = c;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值