albertonline· portal
blind75

Group Anagrams: Categorizing Words by Character Composition

Jan 14, 2024 · Solving the Group Anagrams problem by categorizing a list of strings into groups where each group consists of words that are anagrams of each other.

The "Group Anagrams" problem involves categorizing a list of strings into groups, where each group contains words that are anagrams of each other.

Problem Statement

Given an array of strings, group the anagrams together. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Example

  • Input: ["eat", "tea", "tan", "ate", "nat", "bat"]
  • Output: [["ate","eat","tea"], ["nat","tan"], ["bat"]]

Solution Approach - Hashing and Sorting

javascript

Breaking Down the Solution


  • Sort and Hash: For each string, sort its characters and use the sorted string as a key in a map.
  • Group Anagrams: Group the original strings by their sorted key in the map.
  • Result: Return the grouped anagrams as an array of arrays.

Solution in Typescript

typescript

In this TypeScript solution:

  • The function groupAnagrams takes an array of strings.
  • A map (Record<string, string[]>) is used to group strings by their sorted form.
  • Each string in the input array is split into characters, sorted, and then joined back to form a key.
  • The original strings are then grouped in the map based on this key.
  • Finally, the function returns the values of the map, which are arrays of anagrams.

This implementation effectively groups anagrams together by using the sorted version of each string as a key, ensuring that all anagrams have the same key and are thus grouped together.

Conclusion


The Group Anagrams problem is an interesting exercise in string manipulation, sorting, and hashing. It demonstrates how to categorize data based on shared characteristics, in this case, the composition of characters.

Rust Solution

rust

Rust's map.entry(key).or_default().push(...) collapses the JS if (!map[k]) map[k] = [] guard into a single call — or_default() inserts an empty Vec<String> on a miss and hands back a mutable reference to push into. The key is built by collecting s.chars() into a Vec<char>, sorting in place with chars.sort(), then re-collecting chars.into_iter() into a String. Because the input is Vec<&str>, each borrowed slice must be promoted with s.to_string() before it can be stored as an owned String. Finally map.into_values() consumes the map to yield the groups, which are sorted in place via groups.iter_mut() and a closing groups.sort() for deterministic output.

Go Solution

go

Go leans on append(groups[key], s) reading a missing key as a zero-value (nil) slice — append grows a nil slice just fine, so no if-guard is needed for the first insertion. Characters are split with strings.Split(s, "") into a []string, ordered by sort.Strings, and rejoined with strings.Join. Unlike Rust's annotated value type, the map is declared inline as the map[string][]string{} composite literal. The final ordering uses sort.Slice with a closure comparator, func(i, j int) bool returning result[i][0] < result[j][0], which compares each group's first element rather than sorting the slices whole.

Comments (0)

Stub comments live in your browser only (localStorage). No server round-trip yet.

No comments yet. Be the first.