NeetCode Blind75 - Valid Anagram - Go vs Python

Learning Go as an AWS engineer, I decided to test my new knowledge of Go maps against a familiar problem: Valid Anagram from NeetCode’s Blind75. Having solved this countless times in Python, it’s perfect for comparing how dictionaries work between the two languages. Btw, here is how I would write it in Python:

from collections import Counter

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        count_s, count_t = Counter(s), Counter(t)
        return count_s == count_t

Simple and clean. Python’s Counter counts character instances in each string, then compares the dictionaries for equality.

Here’s the Go approach. First, create the hashmaps and check string lengths:

// Create a counter dictionary
    counter_s := make(map[rune]int)
    counter_t := make(map[rune]int)

    if len(s) != len(t) {
        return false
    }

You might wonder: what’s a rune? Go doesn’t have characters like Python. Instead, it uses rune to represent individual letters and symbols—Go’s equivalent of a character.

Next, loop through both strings to populate the maps:

for _, value := range(s) {
    rune_value := rune(value)
    counter_s[rune_value]++
}

for _, value := range(t) {
    rune_value := rune(value)
    counter_t[rune_value]++
}

With both dictionaries populated, the next step is comparison. Here’s where I hit my first roadblock:

if counter_s != counter_t {
    return false
} else {
    return true
}

Go threw an error at this conditional. But why? The reason is, Go does not do comparison between dictionaries. You can only test a map against nil.

To rectify this, we need to import the reflect package and use DeepEqual() to compare our maps:

import "reflect"

func isAnagram(s string, t string) bool {
    // Create a counter dictionary
    counter_s := make(map[rune]int)
    counter_t := make(map[rune]int)

    if len(s) != len(t) {
        return false
    }

    for _, value := range(s) {
        rune_value := rune(value)
        counter_s[rune_value]++
    }

    for _, value := range(t) {
        rune_value := rune(value)
        counter_t[rune_value]++
    }

    return reflect.DeepEqual(counter_s, counter_t)
}

Go vs Python: Key Differences Link to heading

AspectPythonGo
Lines of Code3 lines~20 lines
Built-in SupportCounter from collectionsManual map building required
Dictionary ComparisonDirect == comparisonRequires reflect.DeepEqual()
Type HandlingAutomatic string iterationExplicit rune casting needed
Time ComplexityO(n)O(n)
Space ComplexityO(k) where k = unique charsO(k) where k = unique chars
ReadabilityVery concise and readableMore verbose but explicit

Key Takeaway: Python’s built-in Counter makes this problem trivial, while Go requires more manual work but gives you explicit control over the process. The Go solution teaches you more about how hash maps actually work under the hood.

Alternative: Manual Map Comparison Link to heading

What if you can’t use the reflect package say, during a coding interview? You’ll need to manually compare each key-value pair between the maps:

func isAnagram(s string, t string) bool {
    // Create a counter dictionary
    counter_s := make(map[rune]int)
    counter_t := make(map[rune]int)

    if len(s) != len(t) {
        return false
    }

    for _, value := range(s) {
        rune_value := rune(value)
        counter_s[rune_value]++
    }

    for _, value := range(t) {
        rune_value := rune(value)
        counter_t[rune_value]++
    }
    
    // Check if maps have same length (same number of unique characters)
    if len(counter_s) != len(counter_t) {
        return false
    }
    
    // Check each key-value pair
    for key, value := range(counter_s) {
        if counter_t[key] != value {
            return false
        }
    }
    return true
}

This approach first checks if both maps have the same number of unique characters, then compares each key-value pair. It’s more efficient than the previous version and demonstrates proper map comparison logic for interviews.

Key Takeaways Link to heading

  • Go maps can’t be compared directly - Use reflect.DeepEqual() or manual iteration
  • Python’s Counter is more concise - Go requires explicit map building
  • For interviews, use the manual approach - Shows deeper understanding of data structures
  • Both languages achieve O(n) time and space complexity - Different approaches, same efficiency

This problem illustrates the difference between go and python dictionaries and why we can’t do a simple comparison in go.

References Link to heading

  1. Boot.Dev
  2. NeetCode
  3. GeekForGeek Article on Comparing Dictionaries in Go