DEV Community

Usman Ali
Usman Ali

Posted on

Arrays & Hashing: A Beginner’s Guide to the Most Important Pattern in DSA

Arrays & Hashing: A Beginner's Guide to the Most Important Pattern in DSA

If you are just starting out with Data Structures and Algorithms, Arrays & Hashing is where you should begin. Not because it is the easiest — but because it teaches you the most fundamental shift in thinking that carries through almost every other topic.

This guide covers the core patterns you will encounter in this section, why they matter, and how to recognize when to use them.


The Problem With Brute Force

Before getting into HashMaps and HashSets, it helps to understand what problem they solve.

When you first look at a problem like "check if an array has duplicates", the instinctive solution is to compare every element with every other element. Two nested loops. It works — but it runs in O(n²) time, meaning as the input grows, the time it takes grows exponentially.

The question Arrays & Hashing teaches you to ask is: can I trade memory for speed?

In almost every case yes, you can.


Pattern 1: HashSet for Duplicate Detection

A HashSet stores unique values and lets you check membership in O(1) time.

Instead of comparing every pair, you add each element to a set as you go. If you ever try to add something that already exists you found a duplicate.

def containsDuplicate(nums):
    seen = set()
    for num in nums:
        if num in seen:
            return True
        seen.add(num)
    return False
Enter fullscreen mode Exit fullscreen mode

One pass. O(n) time. This is the first mental model shift — stop comparing pairs, start tracking what you have seen.

When to reach for a HashSet: Any time a problem asks about duplicates, uniqueness, or membership checks.


Pattern 2: HashMap for Counting Frequency

A HashMap (dictionary in Python) maps keys to values. When the value is a count, you get a powerful frequency tracker.

The classic use case is checking if two strings are anagrams they have the same characters in different orders. Count the frequency of each character in both strings. If the counts match, they are anagrams.

def isAnagram(s, t):
    count = {}
    for char in s:
        count[char] = count.get(char, 0) + 1
    for char in t:
        count[char] = count.get(char, 0) - 1
    return all(v == 0 for v in count.values())
Enter fullscreen mode Exit fullscreen mode

When to reach for a HashMap with counts: Any time a problem involves frequency, occurrence, or character/element distribution.


Pattern 3: HashMap for Complement Lookup

This is the pattern behind Two Sum — one of the most common interview problems.

Instead of checking every pair (O(n²)), you store each number in a HashMap as you iterate. For each new number, you check if its complement (target minus current number) already exists in the map.

def twoSum(nums, target):
    seen = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i
Enter fullscreen mode Exit fullscreen mode

You find the answer in a single pass. The HashMap does the lookup work for you in O(1).

When to reach for this pattern: Any time a problem asks you to find a pair that satisfies a condition.


Pattern 4: HashMap for Grouping

Some problems ask you to group elements that share a property. Group Anagrams is the clearest example group all words that are anagrams of each other.

The trick is finding a key that all members of a group share. For anagrams, sorting the word gives you that key "eat", "tea", and "ate" all sort to "aet".

def groupAnagrams(strs):
    groups = {}
    for word in strs:
        key = "".join(sorted(word))
        if key not in groups:
            groups[key] = []
        groups[key].append(word)
    return list(groups.values())
Enter fullscreen mode Exit fullscreen mode

When to reach for this pattern: Any time you need to group items by a shared characteristic the sorted version, the frequency signature, or any derived property.


Pattern 5: HashSet for Sequence Detection

Longest Consecutive Sequence introduces a clever idea use a HashSet not just for lookup, but to find where sequences begin.

You only start counting a sequence if the element before it does not exist in the set. This avoids counting the same sequence multiple times and keeps the solution at O(n).

def longestConsecutive(nums):
    num_set = set(nums)
    longest = 0
    for num in num_set:
        if num - 1 not in num_set:  # start of a sequence
            length = 1
            while num + length in num_set:
                length += 1
            longest = max(longest, length)
    return longest
Enter fullscreen mode Exit fullscreen mode

When to reach for this pattern: Sequence problems where you need to detect starts and avoid redundant work.


The Mental Model to Take Away

Arrays & Hashing is not really about memorizing solutions. It is about developing one instinct:

When brute force requires nested loops ask if a HashMap or HashSet can replace the inner loop.

Here is a quick reference for when to reach for what:

Situation Tool
Check for duplicates HashSet
Count frequency of elements HashMap
Find a pair that meets a condition HashMap (complement lookup)
Group elements by shared property HashMap with derived key
Detect sequences efficiently HashSet (check for sequence start)

Once this instinct is developed, you will start seeing these patterns everywhere not just in Arrays & Hashing, but across the entire DSA landscape.


Top comments (0)