Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.thealgorithms.Recursion;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class UniquePermutations {

public static List<String> getUniquePermutations(String str) {
// Handle null or empty input
if (str == null) return new ArrayList<>();
if (str.length() == 0) {
List<String> result = new ArrayList<>();
result.add("");
return result;
}

// Sort characters to handle duplicates
char[] chars = str.toCharArray();
Arrays.sort(chars);

List<String> result = new ArrayList<>();
boolean[] used = new boolean[chars.length];
StringBuilder currentPermutation = new StringBuilder();
generatePermutations(chars, used, currentPermutation, result);
return result;
}

private static void generatePermutations(char[] chars, boolean[] used, StringBuilder currentPermutation, List<String> result) {
if (currentPermutation.length() == chars.length) {
result.add(currentPermutation.toString());
return;
}

for (int i = 0; i < chars.length; i++) {
// Skip used characters or duplicates
if (used[i] || (i > 0 && chars[i] == chars[i - 1] && !used[i - 1])) {
continue;
}
used[i] = true;
currentPermutation.append(chars[i]);
generatePermutations(chars, used, currentPermutation, result);
used[i] = false;
currentPermutation.deleteCharAt(currentPermutation.length() - 1);
}
}
}


//This is a more efficient but complex algorithm
//If you want to refer to a simpler one and then come to this,
//click on the URL=>"https://www.geeksforgeeks.org/java-program-to-print-distinct-permutations-of-a-string/""
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.thealgorithms.Recursion;

import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class UniquePermutationsTest {

@Test
void testUniquePermutations() {
String str = "abc";
List<String> expected = List.of("abc", "acb", "bac", "bca", "cab", "cba");
List<String> result = UniquePermutations.getUniquePermutations(str);
Collections.sort(expected); // Ensure expected is sorted
Collections.sort(result); // Ensure result is sorted
assertEquals(expected, result);
}

@Test
void testUniquePermutationsWithDuplicates() {
String str = "aab";
List<String> expected = List.of("aab", "aba", "baa");
List<String> result = UniquePermutations.getUniquePermutations(str);
Collections.sort(expected); // Ensure expected is sorted
Collections.sort(result); // Ensure result is sorted
assertEquals(expected, result);
}

@Test
void testEmptyString() {
String str = "";
List<String> result = UniquePermutations.getUniquePermutations(str);
assertEquals(1, result.size()); // only 1 permutation which is an empty string
assertEquals("", result.get(0)); // Verify the only permutation is the empty string
}

@Test
void testSingleCharacter() {
String str = "a";
List<String> result = UniquePermutations.getUniquePermutations(str);
assertEquals(1, result.size());
assertEquals("a", result.get(0));
}

@Test
void testAllIdenticalCharacters() {
String str = "aaa";
List<String> expected = List.of("aaa");
List<String> result = UniquePermutations.getUniquePermutations(str);
assertEquals(expected.size(), result.size());
assertEquals(expected, result);
}

@Test
void testMixedCaseCharacters() {
String str = "aAb";
List<String> expected = List.of("AaB", "AbA", "aAB", "aBA", "baA", "bAa");
List<String> result = UniquePermutations.getUniquePermutations(str);
Collections.sort(expected); // Ensure expected is sorted
Collections.sort(result); // Ensure result is sorted
assertEquals(expected, result);
}

@Test
void testNullInput() {
String str = null;
List<String> result = UniquePermutations.getUniquePermutations(str);
assertEquals(0, result.size()); // Expect an empty list for null input
}
}
Loading