2

Which is the best way of generating anagrams for a text(maximum 80 characters length). Example: Input: dog output dog dgo odg ogd gdo god

I'm only thinking of a backtracking solution, but that will take a while if the text is longer.

Another thought is bulding i trie for all words in dictionary, but the problem doesn't ask for real words.

Can somebody point out a minimum time complexity solution?

Thank you!

Dan Dinu
  • 32,492
  • 24
  • 78
  • 114

3 Answers3

8

here is a straight-forward implementation, just in case you need one:

IEnumerable<List<T>> Permutations<T>(List<T> items)
{
    if (items.Count == 0) yield return new List<T>();

    var copy = new List<T>(items);
    foreach (var i in items)
    {
        copy.Remove(i);
        foreach (var rest in Permutations(copy))
        {
            rest.Insert(0, i);
            yield return rest;
        }
        copy.Insert(0, i);
    }

}

IEnumerable<string> Anagrams(string word)
{
    return Permutations(word.ToCharArray().ToList()).Select(x => new String(x.ToArray()));
}

The answer concerning the time-complexity gave Adithya. To understand their answer you have to know that there are n! = 1*2*...*n permutations for n items. My algorithm is a proof for that (or based on the straight forward proof)

boop
  • 7,413
  • 13
  • 50
  • 94
Random Dev
  • 51,810
  • 9
  • 92
  • 119
5

The question looks like generating the list of permutations; (Anagrams are a subset of permutations, which form a meaningful word). n! Permutations can be generated in chronological order using the approach of STL's next_permutation, (linear time complexity per permutation); You can find the discussion of this algorithm here: http://marknelson.us/2002/03/01/next-permutation/ ; STL's algorithm can even handle duplicates and the naive swap algorithm fails in this case.

For a indepth discussion on generating permutations, you can go through Donald Knuth's Generating all Perumutations section of TAOCP.

vine'th
  • 4,890
  • 2
  • 27
  • 27
3

Backtracking is the fastest way to go, When you want all the anagrams for a text, it means you need all the n! permutations of it. So assuming printing/generating each permutation takes O(1) atleast, your algorithm would take O(n!) anyways, hence you cant do quicker than a backtracking solution.

Adithya Surampudi
  • 4,354
  • 1
  • 17
  • 17
  • 1
    yeah, O(80!)... couple of years! – stukselbax Aug 25 '11 at 08:44
  • what happens when the input string contains same letters: Eg: input:aba output should be: aab aba baa. i don't need duplicates. Do i have to compare the current result with all the previos results in order not to get duplicates? – Dan Dinu Aug 25 '11 at 08:50
  • You could either have a hash containing discovered permutations or if there are too many duplicates, you can build a trie, but be a bit careful here. Each node would have a hashmap of characters mapped to their number of occurences remaining, generate child nodes with these characters and decrement the counter of the child node character in its hashmap and remove key if count is 0. Root would have all unique characters as keys mapped to their number of occurences, leaf would have an empty map. Now print all paths to leaves for your solution. If all characters are same, this would take O(n). – Adithya Surampudi Aug 25 '11 at 09:11
  • @Dan Dinu store all results in Hashtable, so check will be O(1) – blaze Aug 25 '11 at 09:17