【问题标题】:Return all permutations of a given list recursively递归返回给定列表的所有排列
【发布时间】:2021-09-19 09:45:04
【问题描述】:

以下算法打印给定列表arr的所有排列:

public class Permute {
    static void permute(java.util.List<Integer> arr, int k) {
        for (int i = k; i < arr.size(); i++) {
            java.util.Collections.swap(arr, i, k);
            permute(arr, k + 1);
            java.util.Collections.swap(arr, k, i);
        }
        if (k == arr.size() - 1) {
            System.out.println(java.util.Arrays.toString(arr.toArray()));
        }
    }

    public static void main(String[] args) {
        Permute.permute(java.util.Arrays.asList(1, 2, 3), 0);
    }
}

(仅供参考:算法取自this答案)

我想修改算法,使其返回所有解决方案的列表,而不是打印它们,例如:

static List<List<Integer>> permute(java.util.List<Integer> arr, int k);

我该怎么做?我尝试了以下算法的修改,但没有奏效:

public class Permute {
    static List<List<Integer>> permute(java.util.List<Integer> arr, int k) {
        List<List<Integer>> arrs = new ArrayList<>();
        for (int i = k; i < arr.size(); i++) {
            java.util.Collections.swap(arr, i, k);
            arrs.addAll(permute(arr, k + 1));
            java.util.Collections.swap(arr, k, i);
        }
        if (k == arr.size() - 1) {
            arrs.add(arr);
            System.out.println(java.util.Arrays.toString(arr.toArray()));
        }
        return arrs;
    }

    public static void main(String[] args) {
        List<Integer> arr = new ArrayList<>(Arrays.asList(1, 2, 3));
        System.out.println(Permute.permute(arr, 0));
    }
}

代码编译并执行,但给出了错误的结果[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]。我无法理解为什么代码不起作用以及如何正确执行。任何帮助表示赞赏。

【问题讨论】:

    标签: java algorithm recursion permutation


    【解决方案1】:

    您需要将List 的副本添加到结果中,而不是每次都添加相同的。

    改变

    arrs.add(arr);
    

    arrs.add(new ArrayList<>(arr));
    

    完整方法:

    static List<List<Integer>> permute(java.util.List<Integer> arr, int k) {
        List<List<Integer>> arrs = new ArrayList<>();
        for (int i = k; i < arr.size(); i++) {
            java.util.Collections.swap(arr, i, k);
            arrs.addAll(permute(arr, k + 1));
            java.util.Collections.swap(arr, k, i);
        }
        if (k == arr.size() - 1) {
            arrs.add(new ArrayList<>(arr));
        }
        return arrs;
    }
    

    Demo

    【讨论】:

      【解决方案2】:

      正如 Unmitigated 所指出的,您需要添加置换列表的副本。

      此外,无需创建新列表来保存每个递归级别的排列。您可以创建一个列表来保存结果并将其作为参数传递:

      static void permute(List<List<Integer>> res, List<Integer> arr, int k) {
        if (k == arr.size() - 1) {
          res.add(new ArrayList<>(arr));
          return;
        }
      
        for (int i = k; i < arr.size(); i++) {
          Collections.swap(arr, i, k);
          permute(res, arr, k + 1);
          Collections.swap(arr, k, i);
        }
      }
      
      public static void main(String[] args) {
        List<List<Integer>> res = new ArrayList<>();
        permute(res, Arrays.asList(1, 2, 3), 0);
        System.out.println(res);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-18
        • 2012-05-05
        • 1970-01-01
        • 1970-01-01
        • 2020-02-23
        • 2020-01-22
        • 1970-01-01
        相关资源
        最近更新 更多