Reputation: 508
The following algorithm prints all permutations of a given list 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);
}
}
(FYI: The algorithm is taken from this answer)
I would like to modify the algorithm so that it returns a list of all solutions instead of printing them, i.e. something like:
static List<List<Integer>> permute(java.util.List<Integer> arr, int k);
How would I do this? I tried the following modification of the algorithm, but it didn't work:
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));
}
}
The code compiles and executes, but gives the wrong result of [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
. I'm having trouble seeing why the code doesn't work and how to do it correctly. Any help is appreciated.
Upvotes: 1
Views: 659
Reputation: 5455
As Unmitigated has pointed out, you need to add a copy of the permuted list.
Also, there's no need to create a new list to hold permutations at each level of the recursion. You could create a single list to hold the results and pass it as an argument:
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);
}
Upvotes: 1
Reputation: 89139
You need to add a copy of the List
to the result instead of adding the same one each time.
Change
arrs.add(arr);
To
arrs.add(new ArrayList<>(arr));
Full method:
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;
}
Upvotes: 1