Java程序中的重复排列

Java程序中的重复排列,java,recursion,permutation,Java,Recursion,Permutation,我读过一个递归生成字符串排列的算法 调用j=1的函数 if(j==字符串长度) 打印字符串并返回 其他的 对于(i=j表示字符串长度) 将第j个字符与第i个字符交换 调用j+1上的函数 我使用java实现了这一点,如下所示: 类置换{ 私有整数计数=1; 私有字符[]arr={'A','B','C'}; 公共无效perm(整数k){ 如果(k==3){ 系统输出打印(计数+++“); 对于(int i=0;i

我读过一个递归生成字符串排列的算法

调用j=1的函数
if(j==字符串长度)
打印字符串并返回
其他的
对于(i=j表示字符串长度)
将第j个字符与第i个字符交换
调用j+1上的函数
我使用java实现了这一点,如下所示:

类置换{
私有整数计数=1;
私有字符[]arr={'A','B','C'};
公共无效perm(整数k){
如果(k==3){
系统输出打印(计数+++“);
对于(int i=0;i<3;++i)
系统输出打印(arr[i]+“”);
System.out.println();
返回;
}

对于(int i=k;i如果“源”数组保持不变,则该算法有效,因此每个索引都将得到正确处理

让我们看看代码的输出:

1.A B C
2.A C B
3.CAB
4.cba
5.A B C
6.A、C、B

如您所见,在第3次迭代中,应该将B移到第一个索引,而将C移到另一个位置,因为您已经将B移到了另一个位置。 由于这个事实,B没有机会进入第一个指数,只会在2到3之间“反弹”

您的主要问题是,您正在更改“源”数组。如果您避免了这一点,则您的算法工作正常:

class PERMUTATION {
    private int count = 1;

    public void perm(char[] arr, int k) {
        if (k == 3) {
            System.out.print(count++ + ".");
            for (int i = 0; i < 3; ++i)
                System.out.print(arr[i] + "  ");
            System.out.println();
            return;
        }
        char[] arr2 = arr.clone(); // clone the passed array, so we don't mess it up
        for (int i = k; i <= 3; ++i) {
            /* interchanging ith character with kth character */
            char c = arr2[k - 1];
            arr2[k - 1] = arr2[i - 1];
            arr2[i - 1] = c;
            perm(arr2, k + 1);
        }
    }

    public static void main(String[] args) {
        System.out.println("the permutations are");
        PERMUTATION obh = new PERMUTATION();
        obh.perm(new char[] {'A', 'B', 'C'}, 1); // pass the original array
    }
}
类置换{
私有整数计数=1;
公共void perm(字符[]arr,int k){
如果(k==3){
系统输出打印(计数+++“);
对于(int i=0;i<3;++i)
系统输出打印(arr[i]+“”);
System.out.println();
返回;
}
char[]arr2=arr.clone();//克隆传递的数组,这样就不会弄乱它

对于(int i=k;i如果“源”数组保持不变,则该算法有效,因此每个索引都将得到正确处理

让我们看看代码的输出:

1.A B C
2.A C B
3.CAB
4.cba
5.A B C
6.A、C、B

如您所见,在第3次迭代中,应该将B移到第一个索引,而将C移到另一个位置,因为您已经将B移到了另一个位置。 由于这个事实,B没有机会进入第一个指数,只会在2到3之间“反弹”

您的主要问题是,您正在更改“源”数组。如果您避免了这一点,则您的算法工作正常:

class PERMUTATION {
    private int count = 1;

    public void perm(char[] arr, int k) {
        if (k == 3) {
            System.out.print(count++ + ".");
            for (int i = 0; i < 3; ++i)
                System.out.print(arr[i] + "  ");
            System.out.println();
            return;
        }
        char[] arr2 = arr.clone(); // clone the passed array, so we don't mess it up
        for (int i = k; i <= 3; ++i) {
            /* interchanging ith character with kth character */
            char c = arr2[k - 1];
            arr2[k - 1] = arr2[i - 1];
            arr2[i - 1] = c;
            perm(arr2, k + 1);
        }
    }

    public static void main(String[] args) {
        System.out.println("the permutations are");
        PERMUTATION obh = new PERMUTATION();
        obh.perm(new char[] {'A', 'B', 'C'}, 1); // pass the original array
    }
}
类置换{
私有整数计数=1;
公共void perm(字符[]arr,int k){
如果(k==3){
系统输出打印(计数+++“);
对于(int i=0;i<3;++i)
系统输出打印(arr[i]+“”);
System.out.println();
返回;
}
char[]arr2=arr.clone();//克隆传递的数组,这样就不会弄乱它

对于(int i=k;这是否意味着这个算法的空间复杂度是O(n)?@Dante我想它要多一点…可能是O(2n)(由于6个最终结果)甚至O(3n),因为我们需要一些递归,在我们找到单个“最终结果”之前。我们在每个
perm
调用中克隆源数组,因此会有很多克隆,但它们的生命周期相对较短,因此可以快速进行垃圾收集。这是否意味着此算法的空间复杂度为O(n)?@Dante我猜它要高一点…可能是O(2n)(由于6个最终结果)甚至O(3n),因为我们需要一些递归,在找到单个“最终结果”之前。我们在每个
perm
调用中克隆源数组,因此会有很多克隆,但它们的生命周期相对较短,因此可以快速进行垃圾收集。