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
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
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
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())
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
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
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:
- Try for 15–20 minutes before looking at anything.
- Watch the explanation after, not before.
- 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)