Booking.com Interview Question

Implement a function all_anagram_groups() that, given many input strings, will identify and group words that are anagrams of each other. An anagram is word that is just a re-arrangement of the characters of another word, like "reap" and "pear" and "a per" (whitespace is ignored). But "pear" and "rep" are not, since "rep" does not have an "a". Also, "the" and "thee" are not anagrams, because "the" only has one "e". Given this example input: [ "pear","dirty room","amleth","reap","tinsel","hamlet","dormitory","listen","silent" ] The output should be an array-of-arrays (or list-of-lists) [ ["pear","reap"], ["dirty room","dormitory"], ["amleth","hamlet"], ["tinsel","listen","silent"] ]

Interview Answers

Anonymous

Aug 25, 2014

public void sort(String[] array) { Hashtable> hash = new Hashtable>(); /* Group words by anagram */ for (String s : array) { String key = sortchars(s); if (!hash.containsKey(key)) hash.put(key, new LinkedList()); LinkedList anagrams = hash.get(key); anagrams.push(s); ​​} ​​ /* Convert hash table to array */ int index = 0; for (String key : hash.keySetQ) { LinkedList list = hash.get(key); for (String t : list) { array[index] = t; index++;​​ } } ​}​

2

Anonymous

Sep 8, 2014

sub anagram { my ( $arr ) = @_; my $ang = +{}; for( @$arr ) { my $word = $_; s/\s//g; push @{ $ang->{ join '', sort split( //, $_ ) } }, $word; } return map{ $ang->{$_} } keys %$ang; }

Anonymous

Apr 10, 2016

In C#, Linq makes the solution very easy. private static List> AllAnagramGroups(string[] input) { var anagramList = input .Select(s => new { original = s, sorted = String.Join("", s.Where(c => c != ' ').OrderBy(c => c)) }) .GroupBy(x => x.sorted) .Select(g => g.Select(x => x.original).ToList()) .ToList(); return anagramList; }