Sherlock and Anagrams

  • + 0 comments

    Java

        public static int sherlockAndAnagrams(String s) {
            Map<String, Integer> occurrences = new HashMap<>();
    
            for (int i = 0; i < s.length(); i++) {
                for (int j = i; j < s.length(); j++) {
                    String val = sortString(s.substring(i, j + 1));
                    occurrences.put(val, occurrences.getOrDefault(val, 0) + 1);
                }
            }
            int anagramPairCount = 0;
            occurrences = removeSingleOccurrences(occurrences);
            for (Map.Entry<String, Integer> e : occurrences.entrySet()) {
                // Once occurrence ‘o’ of each frequency array is stored, total anagrams will be the sum of
                // o*(o-1)/2 for all different frequency arrays because if a particular substring has ‘o’ anagrams in
                // string total o*(o-1)/2 anagram pairs can be formed. Below is the implementation of above idea.
    
                // The division by two is needed to disregard different combinations between two elements:
                // [0, 1] and [1, 0]
                anagramPairCount += (e.getValue() * (e.getValue() - 1)) / 2;
            }
            return anagramPairCount;
        }
    
        private static Map<String, Integer> removeSingleOccurrences(Map<String, Integer> occurrences) {
            return occurrences
                .entrySet()
                .stream()
                .filter(e -> e.getValue() > 1)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        }
    
        private static String sortString(String str) {
            char[] charArray = str.toCharArray();
            Arrays.sort(charArray);
            return String.valueOf(charArray);
        }