From 57bd66c92aa6ba2a7f009a4f63043e71c7b38101 Mon Sep 17 00:00:00 2001 From: jaebradley Date: Thu, 20 Jul 2017 11:01:06 -0400 Subject: [PATCH] added markdown --- .../unorderedAnagrammaticPairsCounter.md | 76 +++++++++++++++++++ ...UnorderedAnagrammaticPairsCounterImpl.java | 5 ++ 2 files changed, 81 insertions(+) create mode 100644 codereview/unorderedAnagrammaticPairsCounter.md diff --git a/codereview/unorderedAnagrammaticPairsCounter.md b/codereview/unorderedAnagrammaticPairsCounter.md new file mode 100644 index 0000000..da797c0 --- /dev/null +++ b/codereview/unorderedAnagrammaticPairsCounter.md @@ -0,0 +1,76 @@ +## Problem + +Adapted from [this HackerRank problem](https://www.hackerrank.com/challenges/sherlock-and-anagrams/problem) + +> Given a string `S`, find the unordered pairs of substrings that are anagrams of each other + +> Two strings are anagrams of each other if the letters of one string can be rearranged to form the other string. + +## Approach + +Another way of thinking about anagrams is that two strings are anagrams if the frequency of the characters in both strings is identical. +In other words, if you were to create a `Map` of the number of times every `Character` is found in each string, both `Map`s should be identical. + +``` +`abba` => `{ 'a': 2, 'b': 2 }` +`bbaa` => `{ 'a': 2, 'b': 2 }` +``` + +Thus, I approached the problem in the following way + +1. Start with a pair count value of `0` +2. Iterate through all substrings of a given length +3. Create a `Map` that will keep track of all anagrams and their frequency (again, for substrings of the given length) +4. For each substring, represent the frequency of each `Character` using a `Map` +5. If the character frequencies calculated in Step #4 are not found in the key values of the `Map` created in Step #3 then + add them to the `Map`. + * If it does exist, then increment the pair count by the number of times the same anagram + (i.e. character frequencies) have already been seen. + * This is because for every time an identical anagram is seen, it can be + paired with every previous instance of the same anagram. + * After incrementing the pair count, also increment the number of times an anagram has been seen by `1` +6. Return the pair count value + + +## Implementation + + + + public class UnorderedAnagrammaticPairsCounter { + + public static int countUnorderedAnagrammaticPairs(String s) { + int count = 0; + + for (int substringLength = 1; substringLength <= s.length(); substringLength++) { + Map, Integer> substringsCounts = new HashMap<>(); + for (int index = 0; index <= s.length() - substringLength; index++) { + String substring = s.substring(index, index + substringLength); + Map characterCounts = UnorderedAnagrammaticPairsCounter.getCharacterCounts(substring); + Integer substringCounts = substringsCounts.get(characterCounts); + if (substringCounts == null) { + substringsCounts.put(characterCounts, 1); + } else { + count += substringCounts; + substringsCounts.put(characterCounts, substringCounts + 1); + } + } + } + + return count; + } + + public static Map getCharacterCounts(String s) { + Map characterCounts = new HashMap<>(); + + for (char c : s.toCharArray()) { + Integer characterCount = characterCounts.get(c); + if (characterCount == null) { + characterCounts.put(c, 1); + } else { + characterCounts.put(c, characterCount + 1); + } + } + + return characterCounts; + } + } \ No newline at end of file diff --git a/src/main/java/algorithms/implementations/UnorderedAnagrammaticPairsCounterImpl.java b/src/main/java/algorithms/implementations/UnorderedAnagrammaticPairsCounterImpl.java index 18c3b59..8c70ad0 100644 --- a/src/main/java/algorithms/implementations/UnorderedAnagrammaticPairsCounterImpl.java +++ b/src/main/java/algorithms/implementations/UnorderedAnagrammaticPairsCounterImpl.java @@ -5,6 +5,11 @@ import java.util.HashMap; import java.util.Map; +/** + * https://www.hackerrank.com/challenges/sherlock-and-anagrams/problem + * https://codereview.stackexchange.com/questions/169768/unordered-substring-anagrammatic-pairs + */ + public class UnorderedAnagrammaticPairsCounterImpl implements UnorderedAnagrammaticPairsCounter { @Override