DEV Community

Victor Ogbonna
Victor Ogbonna

Posted on

I Started DSA This Week. Here's Everything I Learnt, Explained Like You're at a Market

I've been building with AI since 2022. I've shipped hackathon projects, freelanced as a Next.js developer, and written about crypto for a living. But this week I did something I'd been avoiding: I started Data Structures and Algorithms.

I'm working through the NeetCode 150, starting with Arrays & Hashing. My rule for learning: if I can't explain it with a simple everyday picture, I don't understand it yet.

So here's my week, explained that way.

The one idea behind all of it

Every problem this week came down to one thing:

Remember what you've seen, so you don't have to go back and search.

The tool for remembering is a set or a dictionary (hash map). Checking if something is in one of them is instant, no matter how big it gets. That's the whole trick.

1. Contains Duplicate: the bouncer

Problem: Does any number appear more than once?

Picture it: You're a bouncer with a guest list. Someone arrives. Is their name already on the list? Duplicate! If not, write it down and let them in.

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

The slow way is walking around the whole party checking every face for each new guest: O(n²). The guest list makes it O(n).

What I learnt the hard way: my first attempt returned None. My lines were indented one level too deep, sitting under a return, so Python never reached them. Indentation in Python isn't style. It's logic.

2. Valid Anagram: two bags of beads

Problem: Are two words made of exactly the same letters?

Picture it: Two bags of letter beads. Count the beads in each. Same counts? Anagram.

def isAnagram(s, t):
    count_s, count_t = {}, {}
    for letter in s:
        count_s[letter] = count_s.get(letter, 0) + 1
    for letter in t:
        count_t[letter] = count_t.get(letter, 0) + 1
    return count_s == count_t
Enter fullscreen mode Exit fullscreen mode

New tool: a dictionary doesn't just answer "have I seen it?" but "how many times?"

3. Two Sum: shopping with a notebook

Problem: Find the positions of two numbers that add up to a target.

Picture it: You're at a market with ₦7 to spend on exactly two items. At each stall, you work out what partner you'd need (7 − this price) and check your notebook. Seen it already? Done. If not, write down this item and where you saw it, then keep walking.

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

What I learnt the hard way: I typed lens instead of len, then 1 instead of i. The second one didn't crash. It just gave wrong answers. Silent bugs are the dangerous ones.

4. Group Anagrams: the post office

Problem: Group words that are anagrams of each other.

Picture it: A post office. Every word gets a label made from its letters sorted alphabetically ("cat" → "act", "tops" → "opst"). Words with the same label go in the same pigeonhole.

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

Same dictionary, but now it stores label → list of words.

5. Top K Frequent Elements: an election

Problem: Return the k most common numbers.

Picture it: Count the votes, rank the candidates, take the top k.

The easy version sorts by votes. The clever version skips sorting entirely: put each candidate on a shelf numbered by their vote count, then walk the shelves from the top down.

def topKFrequent(nums, k):
    count = {}
    for num in nums:
        count[num] = count.get(num, 0) + 1

    shelves = [[] for _ in range(len(nums) + 1)]
    for num, freq in count.items():
        shelves[freq].append(num)

    result = []
    for freq in range(len(shelves) - 1, 0, -1):
        for num in shelves[freq]:
            result.append(num)
            if len(result) == k:
                return result
Enter fullscreen mode Exit fullscreen mode

That's the jump from O(n log n) to O(n), and the jump interviewers look for: "it works" → "it's optimal."

6. Encode and Decode Strings: labelling parcels

Problem: Squash a list of strings into one string, then rebuild the list exactly.

Why it's tricky: you can't just join with commas, because a word might contain a comma.

Picture it: Before every parcel, stick a note saying how long it is: ["Hello", "World"] → "5#Hello5#World". To unpack, read the number, grab exactly that many characters, repeat. You never look inside the word, so nothing in it can confuse you.

def encode(strs):
    return "".join(f"{len(w)}#{w}" for w in strs)

def decode(s):
    result, i = [], 0
    while i < len(s):
        j = i
        while s[j] != "#":
            j += 1
        length = int(s[i:j])
        result.append(s[j + 1 : j + 1 + length])
        i = j + 1 + length
    return result
Enter fullscreen mode Exit fullscreen mode

This is how real network protocols work. It's less of a LeetCode trick and more of a lesson in designing formats.

What I'm taking into next week

Problem Notebook Question it answers
Contains Duplicate Set Have I seen this?
Valid Anagram Dict (counts) How many times?
Two Sum Dict (positions) Have I seen my partner, and where?
Group Anagrams Dict (label → words) Which group does this belong to?
Top K Frequent Dict + shelves Who has the most?

Three habits that are working for me:

  1. Try for 15–20 minutes before looking at anything.
  2. Watch the explanation after, not before.
  3. Re-solve it the next day from memory.

Next week: Two Pointers and Sliding Window.

If you're also starting DSA from a non-CS background (mine's Microbiology), let's learn together. Drop a comment.

Top comments (0)