Generate same unique hash code for all anagrams

前端 未结 6 1174
刺人心
刺人心 2020-12-05 08:34

Recently, I attended an interview and faced a good question regarding hash collisions.

Question : Given a list of strings, print out the anagrams together.

E

6条回答
  •  攒了一身酷
    2020-12-05 09:05

    The complexity above seems very misplaced! You don't need prime numbers or hashes. It's just three simple ops:

    1. Map each OriginalWord to a Tuple of (SortedWord, OriginalWord). Example: "cat" becomes ("act", "cat"); "dog" becomes ("dgo", "dog"). This is a simple sort on the chars of each OriginalWord.
    2. Sort the Tuples by their first element. Example: ("dgo", "dog"), ("act, "cat") sorts to ("act", "cat"), ("dgo", "dog"). This is a simple sort on the entire collection.
    3. Iterate through the tuples (in order), emitting the OriginalWord. Example: ("act", "cat"), ("dgo", "dog") emits "cat" "dog". This is a simple iteration.

    Two iterations and two sorts are all it takes!

    In Scala, it's exactly one line of code:

    val words = List("act", "animal", "dog", "cat", "elvis", "lead", "deal", "lives", "flea", "silent", "leaf", "listen")
    
    words.map(w => (w.toList.sorted.mkString, w)).sorted.map(_._2)
    # Returns: List(animal, act, cat, deal, lead, flea, leaf, dog, listen, silent, elvis, lives)
    

    Or, as the original question implies, you only want cases where the count > 1, it's just a bit more:

    scala> words.map(w => (w.toList.sorted.mkString, w)).groupBy(_._1).filter({case (k,v) => v.size > 1}).mapValues(_.map(_._2)).values.toList.sortBy(_.head)
    res64: List[List[String]] = List(List(act, cat), List(elvis, lives), List(flea, leaf), List(lead, deal), List(silent, listen))
    

提交回复
热议问题