算法:全排列

本文详细介绍了全排列的概念及其实现方式,通过一个具体的例子——字符串'ABC',阐述了全排列的步骤和递归算法。代码部分展示了一个使用Java实现的全排列函数,通过字符交换来生成所有可能的排列组合,并存储在HashSet中。最后,文章展示了运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

全排列

编写一个函数求解某字符串中所有字符的排列(不包括重复)。
例如字符串“ABC”,它的全排列有:
ABC ACB BAC BCA CAB CBA

思路

全排列实际上只需要以下步骤:

  1. 选择“老大”,即将字符串中的其中一个字符移至字符串最前面,当作此字符串的“老大”。
  2. 在除了“老大”字符之外的字串中再选择一个“老大”。
  3. 重复上述步骤,直到字串只有一个字符时,返回上一层,将“老大”更换成没有当过“老大”的字符。如子串中的字符都当过“老大”,则继续返回上一层。

过程

现在用图片进行举例,使用例子为字符串“ABC”。
第一步,选择老大,此时选择字符串的第一个字符当作老大,即“A”为字符串“ABC”的老大。这一个步骤可以理解为自己和自己进行交换位置。
在这里插入图片描述
第二步,在除了老大“A”之外的字串中再选择一个老大,在此时。字符串“BC”的老大为“B”。
在这里插入图片描述
第三步,在除了老大“B”之外的字串中再选择一个老大。字符串“B”的老大为“C”。此时字串中只有一个字符,返回上一层,即“BC”字符串。
第四步,“BC”字符串中,“B”已经当过老大,所以这时将“C”移动到字符串第一个位置,让“C”当老大。“C”当老大时子串中只有一个字符“B”,遍历过后返回上一层。
在这里插入图片描述
第五步,此时子串“BC”中,“B”和“C”都当过了老大,所以继续返回上一层。返回到字符串“ABC”。在上述步骤中,“ABC”中“A”当老大的情况都已经考虑完了,现在选择“B”当做“ABC”的老大,以此类推继续执行上述步骤,如图所示,当“ABC”中所有字符都当过一次老大,则全排列的所有情况就已经全部考虑到了。
在这里插入图片描述
在这里插入图片描述

代码

我们使用递归的方式来实现全排列。使用HashSet存放所有全排列的情况,代码如下:

public class FullPermutation1 {

    public static void main(String[] args) {
        String s = "AB";
        HashSet<String> set = new HashSet<>();
        //参数依次是存放排列的集合、字符串中第0个字符、字符串最后一个字符、字符串转换成字符数组
        Permutation1(set,0,s.length()  - 1,s.toCharArray());
        System.out.println(set.toString());
    }
    //start指针指向字符数组第0个位置,end指向最后一个位置
    private static void Permutation1(HashSet<String> set, int start, int end, char[] s) {
        //递归退出条件:当start指向end时,即数组遍历完成
        if(start == end){
            //将排列情况使用字符串添加进集合set
            set.add(new String(s));
        }
        else{
            for(int i = start;i <= end;i++){
                //第0个字符和第i个字符进行交换,即每个字符都要前移当一次老大
                swap(start,i,s);
                //递归调用,从start的下一个元素开始
                Permutation1(set,start + 1,end,s);
                //排列完此次情况后,将交换过的字符换回来,保证原本字符的顺序
                swap(start,i,s);
            }
        }
    }

    private static void swap(int start, int i,char[] s) {
        char t = s[start];
        s[start] = s[i];
        s[i] = t;
    }
}

运行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值