Last active
October 1, 2018 20:55
-
-
Save leosabbir/f68e8acf86a98520f88e2a6f32462be8 to your computer and use it in GitHub Desktop.
Compute permutations of a string with unique and duplicate characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* File: Permutations.java | |
* Created: 10/1/2018 | |
* Author: Sabbir Manandhar | |
* | |
* Copyright (c) 2018 Hogwart Inc. | |
*/ | |
import java.util.*; | |
//======================================================================================= | |
/** | |
* @author Sabbir Manandhar [email protected] | |
* @version 1.0 | |
*/ | |
public class Permutations { | |
public static void main(String[] args) { | |
List<String> permutations = permutationWithoutDuplicates("ABCD"); | |
for (String permutation : permutations) | |
System.out.println(permutation); | |
System.out.println(); | |
permutations = permuteWithDuplicates("AAABB"); | |
for (String permutation : permutations) | |
System.out.println(permutation); | |
} // main | |
//------------------------------------------------------------------------------------- | |
//------ Solution 1: For Input with Unique Characters Only ----------- | |
/** | |
* Computes permutation of given string without any duplicate characters. | |
* For string duplicate character, results will contain duplicate entries. | |
* @param s input string | |
* @return List of permutations | |
*/ | |
public static List<String> permutationWithoutDuplicates(String s) { | |
char[] chars = s.toCharArray(); | |
List<String> permutations = new ArrayList<>(); | |
permutationWithoutDuplicatesHelper(chars, 0, permutations); | |
return permutations; | |
} // permutationWithoutDuplicates | |
//------------------------------------------------------------------------------------- | |
/** | |
* Recursive helper method to compute permutations of a character array without duplicates. | |
* @param chars input character array | |
* @param cursor pointer to current location considered. Characters before this pointer and kept fixed. | |
* @param permutations List holding resulting permutations | |
*/ | |
private static void permutationWithoutDuplicatesHelper(char[] chars, int cursor, List<String> permutations) { | |
if (cursor == chars.length) { | |
permutations.add(new String(chars)); | |
return; | |
} | |
for (int i = cursor; i < chars.length; i++) { | |
swap(chars, cursor, i); | |
// keep the selected character fixed and compute permutations of remaining characters | |
permutationWithoutDuplicatesHelper(chars, cursor + 1, permutations); | |
swap(chars, cursor, i); | |
} | |
} // permutationWithoutDuplicatesHelper | |
//------------------------------------------------------------------------------------- | |
/** | |
* Utility method to swap two characters in the given character array. | |
* @param chars input character array | |
* @param i first index to swap. | |
* @param j second index to swap. | |
*/ | |
private static void swap(char[] chars, int i, int j) { | |
if (i == j) return; | |
char temp = chars[i]; | |
chars[i] = chars[j]; | |
chars[j] = temp; | |
} // swap | |
//------ END Solution 1 --------------------------------------------------------------- | |
//------------------------------------------------------------------------------------- | |
//------ Solution 2: For Input with Duplicate Characters ------------------------------ | |
/** | |
* Computes permutation of an string with Duplicate characters. | |
* Obviously, it will also work for the string with unique characters. | |
* @param s input string. | |
* @return Permutations of given input. | |
*/ | |
public static List<String> permuteWithDuplicates(String s) { | |
char[] chars = s.toCharArray(); | |
Map<Character, Integer> frequencyMap = createFrequencyMap(chars); | |
List<String> results = new ArrayList<>(); | |
permuteWithDuplicatesHelper(frequencyMap, new char[s.length()], 0, results); | |
return results; | |
} // permuteWithDuplicates | |
//------------------------------------------------------------------------------------- | |
/** | |
* Recursive helper method to compute permutations of a string with duplicate characters. | |
* @param frequencyMap Map holding character counts of input. | |
* @param permutation current permutation | |
* @param cursor current location in permutation | |
* @param results List of all permutations of input. | |
*/ | |
private static void permuteWithDuplicatesHelper(Map<Character, Integer> frequencyMap, char[] permutation, int cursor, List<String> results) { | |
if (cursor == permutation.length) { | |
results.add(new String(permutation)); | |
return; | |
} | |
for (Map.Entry<Character, Integer> entry : frequencyMap.entrySet()) { | |
if (entry.getValue() > 0) { | |
permutation[cursor] = entry.getKey(); | |
entry.setValue(entry.getValue() - 1); | |
permuteWithDuplicatesHelper(frequencyMap, permutation, cursor + 1, results); | |
entry.setValue(entry.getValue() + 1); | |
} | |
} | |
} // permuteWithDuplicatesHelper | |
//------------------------------------------------------------------------------------- | |
/** | |
* Utility method to create character counts as a Map. | |
* @param chars input character array | |
* @return Character Counts Map. | |
*/ | |
private static Map<Character, Integer> createFrequencyMap(char[] chars) { | |
Map<Character, Integer> result = new HashMap<>(); | |
for (Character c : chars) { | |
if (result.containsKey(c)) { | |
result.put(c, result.get(c) + 1); | |
} else { | |
result.put(c, 1); | |
} | |
} | |
return result; | |
} // createFrequencyMap | |
//------ END Solution 2 --------------------------------------------------------------- | |
} // Permutations |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment