Skip to content

Commit fdf5fd1

Browse files
Refactor permutations implementation, fix formatting, add tests
1 parent 9509e4d commit fdf5fd1

2 files changed

Lines changed: 89 additions & 58 deletions

File tree

src/main/java/com/thealgorithms/recursion/Permutations.java

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,90 +2,99 @@
22

33
import java.util.ArrayList;
44
import java.util.Arrays;
5-
import java.util.HashSet;
65
import java.util.List;
7-
import java.util.stream.Collectors;
86

97
/**
10-
* The Permutations class provides utility methods to generate all possible
11-
* rearrangements of elements for both integer arrays and strings.
12-
*
13-
* <p>This implementation uses a recursive approach and a {@link HashSet}
14-
* internally to ensure that only unique permutations are returned.</p>
8+
* This class provides methods to generate all permutations
9+
* of a given integer array or string using recursion.
10+
*
11+
* Reference:
12+
* https://en.wikipedia.org/wiki/Permutation
1513
*/
1614
public final class Permutations {
1715

1816
private Permutations() {
19-
throw new UnsupportedOperationException("Utility Class");
17+
throw new UnsupportedOperationException("Utility class");
2018
}
2119

2220
/**
23-
* Generates all unique permutations of an integer array.
21+
* Generates all permutations of an integer array.
2422
*
25-
* @param nums The array of integers to permute.
26-
* @return A List of Lists, where each inner list is a unique permutation.
27-
* @throws NullPointerException if nums is null.
23+
* @param nums the input array
24+
* @return list of all permutations
25+
* @throws NullPointerException if nums is null
2826
*/
29-
public static List<List<Integer>> permutation(int[] nums) {
30-
if (nums == null) throw new NullPointerException("Input array cannot be null");
31-
32-
List<Integer> up = Arrays.stream(nums).boxed().collect(Collectors.toList());
33-
HashSet<List<Integer>> set = generatePermutations(new ArrayList<>(), up);
34-
return new ArrayList<>(set);
35-
}
36-
37-
/**
38-
* Internal recursive helper to build permutations for integer lists.
39-
*/
40-
private static HashSet<List<Integer>> generatePermutations(List<Integer> p, List<Integer> up) {
41-
HashSet<List<Integer>> result = new HashSet<>();
42-
if (up.isEmpty()) {
43-
result.add(new ArrayList<>(p));
44-
return result;
27+
public static List<List<Integer>> permutations(int[] nums) {
28+
if (nums == null) {
29+
throw new NullPointerException("Input array cannot be null");
4530
}
4631

47-
Integer num = up.get(0);
48-
List<Integer> remaining = up.subList(1, up.size());
32+
List<List<Integer>> result = new ArrayList<>();
33+
List<Integer> list = new ArrayList<>();
4934

50-
for (int i = 0; i <= p.size(); i++) {
51-
List<Integer> nextP = new ArrayList<>(p);
52-
nextP.add(i, num); // Insert num at every possible position
53-
result.addAll(generatePermutations(nextP, remaining));
35+
for (int num : nums) {
36+
list.add(num);
5437
}
5538

39+
generateIntegerPermutations(0, list, result);
5640
return result;
5741
}
5842

59-
/**
60-
* Generates all possible permutations of a given string.
61-
*
62-
* @param s The string to permute.
63-
* @return A List containing all permutations of the input string.
64-
* @throws NullPointerException if s is null.
65-
*/
66-
public static List<String> permutation(String s) {
67-
if (s == null) throw new NullPointerException("Input string cannot be null");
68-
return generateStringPermutations("", s);
43+
private static void generateIntegerPermutations(
44+
int index,
45+
List<Integer> list,
46+
List<List<Integer>> result
47+
) {
48+
if (index == list.size()) {
49+
result.add(new ArrayList<>(list));
50+
return;
51+
}
52+
53+
for (int i = index; i < list.size(); i++) {
54+
swap(list, index, i);
55+
generateIntegerPermutations(index + 1, list, result);
56+
swap(list, index, i); // backtrack
57+
}
58+
}
59+
60+
private static void swap(List<Integer> list, int i, int j) {
61+
Integer temp = list.get(i);
62+
list.set(i, list.get(j));
63+
list.set(j, temp);
6964
}
7065

7166
/**
72-
* Internal recursive helper to build permutations for strings.
67+
* Generates all permutations of a string.
68+
*
69+
* @param s the input string
70+
* @return list of all permutations
71+
* @throws NullPointerException if s is null
7372
*/
74-
private static List<String> generateStringPermutations(String p, String up) {
75-
List<String> list = new ArrayList<>();
76-
if (up.isEmpty()) {
77-
list.add(p);
78-
return list;
73+
public static List<String> permutations(String s) {
74+
if (s == null) {
75+
throw new NullPointerException("Input string cannot be null");
7976
}
8077

81-
char ch = up.charAt(0);
82-
String remaining = up.substring(1);
78+
List<String> result = new ArrayList<>();
79+
generateStringPermutations("", s, result);
80+
return result;
81+
}
82+
83+
private static void generateStringPermutations(
84+
String prefix,
85+
String remaining,
86+
List<String> result
87+
) {
88+
if (remaining.isEmpty()) {
89+
result.add(prefix);
90+
return;
91+
}
8392

84-
for (int i = 0; i <= p.length(); i++) {
85-
String first = p.substring(0, i);
86-
String second = p.substring(i);
87-
list.addAll(generateStringPermutations(first + ch + second, remaining));
93+
for (int i = 0; i < remaining.length(); i++) {
94+
char ch = remaining.charAt(i);
95+
String next =
96+
remaining.substring(0, i) + remaining.substring(i + 1);
97+
generateStringPermutations(prefix + ch, next, result);
8898
}
89-
return list;
9099
}
91-
}
100+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.thealgorithms.recursion;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import java.util.List;
6+
import org.junit.jupiter.api.Test;
7+
8+
class PermutationsTest {
9+
10+
@Test
11+
void testIntegerPermutations() {
12+
int[] nums = {1, 2};
13+
List<List<Integer>> result = Permutations.permutations(nums);
14+
assertEquals(2, result.size());
15+
}
16+
17+
@Test
18+
void testStringPermutations() {
19+
List<String> result = Permutations.permutations("ab");
20+
assertEquals(2, result.size());
21+
}
22+
}

0 commit comments

Comments
 (0)