基础算法-全排列

无去重全排列

对于某个元素作为开头的序列,如果知道了它右边的元素的全排列,就知道了以它开头的全排列

如果序列后面的元素都跟第一个元素交换位置,就知道了每个元素开头的全排列,也就知道了整个序列的全排列。

 public static void permutation1(int a[],int k,int n){
        if(k>=n){
            for(int i=0;i<n;i++)
                System.out.print(a[i]+" ");
            System.out.println();
        }else{
           for(int i=k;i<n;i++){
               swap(a,k,i);
               permutation1(a,k+1,n);
               swap(a,k,i);
           }
        }
    }

这个对于任意元素都唯一的序列来说没有什么问题,但是如果有重复元素,可能产生重复的排列。比如 1,2,2

1 跟第一个 2 交换 : 2,1,2

1 跟第二个 2 交换 : 2,1,2

去重全排列

可以考虑这样来去重,每次交换 i,j 的元素的时候,必须要在 [i,j) 的区间内没有元素与 a[j] 相同。

也就是重复元素只能交换到第一个位置一次。

这样 :

1,2,2

1 跟第一个 2 交换 : 2,1,2

对于 [1,2] 序列 有 2,2,1


 public static boolean hasJ(int a[],int i,int j){
        for(int k=i;k<j;k++){
            if(a[k]==a[j])
                return true;
        }
        return false;
    }

    public static void permutation2(int a[],int k,int n){
        if(k>=n){
            for(int i=0;i<n;i++)
                System.out.print(a[i]+" ");
            System.out.println();
        }else{
            for(int i=k;i<n;i++){
                if(!hasJ(a,k,i)){
                    swap(a,k,i);
                    permutation2(a,k+1,n);
                    swap(a,k,i);
                }
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/yzr1183739890/article/details/56845675