mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-12-19 07:00:35 +08:00
backtracking: add unique permutation algorithm with test cases (#7078)
* Add unique permutation algorithm and test cases * Fix: add braces for checkstyle * Apply clang-format
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Generates all UNIQUE permutations of a string, even when duplicate characters exist.
|
||||
*
|
||||
* Example:
|
||||
* Input: "AAB"
|
||||
* Output: ["AAB", "ABA", "BAA"]
|
||||
*
|
||||
* Time Complexity: O(n! * n)
|
||||
*/
|
||||
public final class UniquePermutation {
|
||||
|
||||
private UniquePermutation() {
|
||||
// Prevent instantiation
|
||||
throw new UnsupportedOperationException("Utility class");
|
||||
}
|
||||
|
||||
public static List<String> generateUniquePermutations(String input) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if (input == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
char[] chars = input.toCharArray();
|
||||
Arrays.sort(chars); // important: sort to detect duplicates
|
||||
|
||||
backtrack(chars, new boolean[chars.length], new StringBuilder(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void backtrack(char[] chars, boolean[] used, StringBuilder current, List<String> result) {
|
||||
|
||||
if (current.length() == chars.length) {
|
||||
result.add(current.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
|
||||
// skip duplicates
|
||||
if (i > 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!used[i]) {
|
||||
used[i] = true;
|
||||
current.append(chars[i]);
|
||||
|
||||
backtrack(chars, used, current, result);
|
||||
|
||||
// undo changes
|
||||
used[i] = false;
|
||||
current.deleteCharAt(current.length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class UniquePermutationTest {
|
||||
|
||||
@Test
|
||||
void testUniquePermutationsAab() {
|
||||
List<String> expected = Arrays.asList("AAB", "ABA", "BAA");
|
||||
List<String> result = UniquePermutation.generateUniquePermutations("AAB");
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUniquePermutationsAbc() {
|
||||
List<String> expected = Arrays.asList("ABC", "ACB", "BAC", "BCA", "CAB", "CBA");
|
||||
List<String> result = UniquePermutation.generateUniquePermutations("ABC");
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyString() {
|
||||
List<String> expected = Arrays.asList("");
|
||||
List<String> result = UniquePermutation.generateUniquePermutations("");
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user