使用迭代实现全排列(Java实现)

之前遇到实现全排列这个问题,也是思考了好久,现在将学习的过程做一简单小结:

一、无重复元素全排列

无重复元素全排列即需要全排列的元素中没有重复的,这种情况使用递归算是比较简单一点,在这里主要以整数数组{1,2,3,4}为例,做一简单分析,如果需要对其他元素进行全排列,只需将里面的元素进行替换即可。
使用递归进行实现全排列,主要的思想就是逐个固定,让后面的元素依次交换位置,最后实现全排列:
1、一个数的全排列:只有本身这一种情况。
2、两个数的全排列:如排列{1,2};
第一步:将元素1放在位置0并固定,剩下的部分{2}进行全排列(与情况1一致,可使用上一步操作),即{1,2};
第二步:将元素2放在位置0并固定,剩下的部分{1}进行全排列(与情况1一致,可使用上一步操作),即{2,1}。
3、三个数的全排列:如排列{1,2,3};
第一步:将元素1放在位置0并固定,剩下的部分{2,3}进行全排列(与情况2一致,可使用上一步操作),即{1,2,3}和{1,3,2};
第二步:将元素2放在位置0并固定,剩下的部分{1,3}进行全排列(与情况2一致,可使用上一步操作),即{2,1,3}和{2,3,1};
第三步:将元素3放在位置0并固定,剩下的部分{1,2}进行全排列(与情况2一致,可使用上一步操作),即{3,1,2}和{3,2,1}。
看到这里,基本应该很清楚了,也能总结m个元素的规律:
4、m个数全排列:就是将m个数依次放在第0个位置并固定,剩下的部分再次进行全排列,依次递归,最后,一个数的全排列作为递归的出口。

public class Main {
    private static void permutation(int[] arr , int n) {
        int length = arr.length;
        if(n>=length-1) {//当n定位到最后一个数时,即到递归出口
            for(int i:arr) {
                System.out.print(i);
            }
            System.out.println();
        }else {
            for(int i=n;i<length;i++) {
                {int temp = arr[n]; arr[n] = arr[i]; arr[i] = temp;}
                permutation(arr,n+1);//对剩下的length-n-1个数全排列
                {int temp = arr[n]; arr[n] = arr[i]; arr[i] = temp;}
            }
        }
    }
    public static void main(String[] args) {
        int[] arr = {1,2,3,4};
        permutation(arr,0);
    }
}

运行结果为:

1234
1243
1324
1342
1432
1423
2134
2143
2314
2341
2431
2413
3214
3241
3124
3142
3412
3421
4231
4213
4321
4312
4132
4123

Process finished with exit code 0

二、有重复元素全排列

有重复元素的全排列,比如{1,2,2,1}这种类型的全排列,基本思路与上述无重复全排列基本一致,但是如果按照第一种的思路会导致大量的重复组合,因此,每次只需在把某个元素放在位置0的时候,判断是否重复即可,具体代码如下:

import java.util.ArrayList;
import java.util.List;

public class Main {
    private static void permutation2(int arr[] , int n) {
        int length = arr.length;
        List<Integer> exis = new ArrayList<Integer>();//存放第零个位置已经有过的数字
        if(n>=length-1) {
            for(int i:arr) {System.out.print(i);}
            System.out.println();
        }else {
            for(int i=n;i<length;i++) {
                if(!exis.contains(arr[i])) { //如果arr[i]不在exis中,则可以把arr[i]放在第零个位置
                    exis.add(arr[i]);//将arr[i]放进exis
                    {int temp = arr[n]; arr[n] = arr[i]; arr[i] = temp;}
                    permutation2(arr,n+1);
                    {int temp = arr[n]; arr[n] = arr[i]; arr[i] = temp;}
                }
            }
        }
    }
    public static void main(String[] args) {
        int[] arr = {1,2,2,1};
        permutation2(arr,0);
    }
}

运行结果如下所示:

1221
1212
1122
2121
2112
2211

在实现全排列的同时,避免了重复。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值