DEV Community

Cover image for What I learned in leetcode 49 Group Anagrams
Di Kan
Di Kan

Posted on

What I learned in leetcode 49 Group Anagrams

Hi this is Di. I am glad to finally begin my blogger life in such an influential platform. I used to write something in my own tiny bare-shell website. But I realized the key to the progress is the spread and clash of the ideas. So I come here. I think the way to a better software engineer, even a better person, learning-criticizing-reflecting-optimizing loop is necessary for my own career and mind. The blog provide me an ideal place to be criticizing and reflecting, and that's the way I always decide to do it. Maybe it's a kind of imitations from the what gurus did.

After leaving the school, i feel like a sense of way different views. The courses to all the corner of the society is open to me now. I feel lost and confused in front of this mist like the tarnished before the mist door. The unknown and big challenge are hiding behind it and unfortunately I can't be brought back by the golden tree in ELDEN RING. Therefore, it's time to sharpen my sword and fight for myself. In the end, it's my own life.

As you can tell prolly, my language expression is not authetic and natural enough. But giving up the practice means ignoring the course to better.

Time to grind.


49.Group Anagrams.

An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, using all the original letters exactly once.
Given a string list, our job is to group all the anagrams.

At first, my idea is to use Counter as a key to store all the words with the same Counter, which can count the frequency of each letter appeared. But the dict can't use a variable as a key.

Then I turned to Gemini for help, which is the best solution to acquire the optimal after my own thinking.

 def groupAnagrams(self, strs):
        # Use a dictionary where the key is the character count tuple
        # and the value is a list of strings belonging to that anagram group
        ans = defaultdict(list)

        for s in strs:
            # Initialize a count array for 26 lowercase English letters
            count = [0] * 26
            for char in s:
                # Calculate the index (0 for 'a', 1 for 'b', etc.)
                count[ord(char) - ord('a')] += 1

            # Convert list to tuple to make it hashable
            ans[tuple(count)].append(s)

        return list(ans.values())
Enter fullscreen mode Exit fullscreen mode

The main idea is to use a 26-length tuple to store the words because the tuple is invariant.

1. defaultdict

ans = defaultdict(list)

defaultdict avoids the pop-out error when the key is not in the dict. We can assign a default data type for those unvisited.

2. ord('a')
ord() stands for the abbr for ordinal. It will return the ASCII number corresponding to a character. ord('a') = 97ord('A') = 65.

By calculating the offset from the 97, we can tell where to count the letter in tuple.

3. list(ans.values()
Maybe you are also curious about why not just return the ans.values instead of listing it?

Actually two different types implement different interfaces. dict_values implements the ValuesView interface, while list implements MutableSequence interface.

"In the Python ecosystem, base interfaces like Sized or Iterable are essentially formal wrappers around a single Protocol. They define a specific capability (e.g., being measurable or traversable). As we move towards more complex structures like Sequence, we see a Composition of Protocols. Understanding this allows us to see data structures not as black boxes, but as a collection of implemented capabilities."

To satisfy the need to judge your solution, official requried the result to be gettable. But ValuesView does not implement that protocal.

Top comments (0)