难以生成排列

时间:2019-01-17 06:01:53

标签: java recursion permutation

在Java中给定一系列不同整数的情况下,我试图生成置换,无法弄清解决方案出了什么问题。

我知道可以在线使用数百种解决方案,但是我正在尝试使用一种对我来说有意义的特定方法来实现它(而不是试图记住别人的算法)。 我的逻辑是,给定{1,2,3,4},我应该遍历并递归打印

1 + permute({2, 3, 4})
2 + permute({1, 3, 4})
3 + permute({1, 2, 4})
4 + permute({1, 2, 3})

因此,基本上将当前元素添加到结果中,然后对其余元素递归调用permute。但是我没有得到正确的结果,我也不知道为什么,我已经盯着代码好几个小时了。

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        ArrayList<List<Integer>> result = new ArrayList<List<Integer>>();
        ArrayList<Integer> tmp = new ArrayList<Integer>();
        getPerm(nums.length, nums, tmp, result);
        return result;
    }

    private void getPerm(int n, int[] a, ArrayList<Integer> tmp, ArrayList<List<Integer>> result){

       // System.out.println("Calling on array " + Arrays.toString(a));
          //  System.out.println("tmp is " + tmp.toString());
          //  System.out.println("n is " + n);



        if(n == 0){
            ArrayList<Integer> toAdd = new ArrayList<Integer>(tmp);
            result.add(toAdd);
            tmp.clear();
           // tmp = new ArrayList<Integer>();
            return;
        }
        for(int i = 0; i < n; i++){
            tmp.add(a[i]);
            int[] b = new int[n-1];
            int k = 0;
            int j = 0;
            while(k<b.length){
                if(a[i]==a[j]){j++;}
                else{b[k]=a[j]; k++; j++;}
            }

            getPerm(n-1, b, tmp, result);
        }
    }
}

For input = [1, 2, 3]
Expect [[1,2,3],[2,1,3],[2,3,1],[1,3,2],[3,1,2],[3,2,1]]
But output is [[1,2,3],[3,2],[2,1,3],[3,1],[3,1,2],[2,1]]

1 个答案:

答案 0 :(得分:0)

让我们遍历输入{1,2,3}的算法:

  • 首先,您将1添加到tmp
  • 然后您调用getPerm(2,[2,3],[1],[])
  • 然后将2加到tmp
  • 然后您将geterm称为(1,[3],[1,2],[])
  • 然后将3加到tmp
  • 然后您调用getPerm(0,[],[1,2,3],[])
  • 现在,您将第一个排列[1、2、3]添加到结果中,并清除tmp
  • 因此下一个应该为[1、3、2]的排列将缺少1

如果在递归调用之后仅删除添加到tmp的最后一个元素,而不是每次都向结果添加排列而不清除tmp,则可以解决此问题:

private void getPerm(int n, int[] a, ArrayList<Integer> tmp, ArrayList<List<Integer>> result)
{
    if(n == 0){
        ArrayList<Integer> toAdd = new ArrayList<Integer>(tmp);
        result.add(toAdd);
        // don't clear tmp here
        return;
    }
    for(int i = 0; i < n; i++){
        tmp.add(a[i]);
        int[] b = new int[n-1];
        int k = 0;
        int j = 0;
        while(k<b.length){
            if(a[i]==a[j]){j++;}
            else{b[k]=a[j]; k++; j++;}
        }

        getPerm(n-1, b, tmp, result);
        tmp.remove(tmp.size()-1); // remove the last element added to tmp
    }
}

现在输出为:

[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]