Skip to Content
Course content

252: Mock Coding Interview Walkthrough in Java

Click on the "Edit" button in the top corner of the screen to edit your slide content.

When I conduct mock interviews, the most common mistake I see isn't a lack of knowledge—it's "coding in a vacuum." A candidate will dive straight into the IDE, write a solution that works for the basic test case, and then completely freeze when the interviewer asks, "What happens if the input is an empty string?" or "Why did you choose a HashMap over an array here?"

Let's look at a piece of code a student of mine wrote recently. We were tackling the "Longest Substring Without Repeating Characters" problem. On the surface, it looks solid, but it has a subtle bug that would likely get them flagged in a real interview.

public int lengthOfLongestSubstring(String s) {
    int n = s.length();
    int maxLength = 0;
    Map<Character, Integer> map = new HashMap<>();
    
    for (int right = 0, left = 0; right < n; right++) {
        char current = s.charAt(right);
        if (map.containsKey(current)) {
            // The bug is right here
            left = map.get(current); 
        }
        map.put(current, right);
        maxLength = Math.max(maxLength, right - left + 1);
    }
    return maxLength;
}

The "Backwards Jump" Bug

If you run this with the string "abcabcbb", it actually works. But try it with "abba". When the loop hits the second 'a' at index 3, it looks at the map and sees the first 'a' was at index 0. It sets left = 0. However, the left pointer had already moved to index 2 because of the double 'b'.

By jumping left back to 0, the code suddenly thinks the substring is "abba", which is obviously wrong. You've essentially allowed your sliding window to expand backward, capturing characters that were already supposed to be excluded. I always tell my students: your window boundaries should only ever move in one direction. If you're moving a "left" pointer, it should only ever go right.

Stabilizing the Sliding Window

To fix this, we need to ensure that left never moves backward. We also need to move left to the position after the last occurrence of the duplicate character, not exactly onto it. Here is how we clean that up:

public int lengthOfLongestSubstring(String s) {
    int n = s.length();
    int maxLength = 0;
    Map<Character, Integer> map = new HashMap<>();
    
    for (int right = 0, left = 0; right < n; right++) {
        char current = s.charAt(right);
        if (map.containsKey(current)) {
            // Fix: Use Math.max to prevent jumping backward 
            // and add 1 to skip the duplicate character.
            left = Math.max(left, map.get(current) + 1);
        }
        map.put(current, right);
        maxLength = Math.max(maxLength, right - left + 1);
    }
    return maxLength;
}

Now, when we hit that second 'a' in "abba", map.get('a') + 1 is 1, but left is already 2. Math.max(2, 1) keeps us at 2. The logic holds, and the window remains valid.

Communicating Your Trade-offs

In a real interview, writing the code is only 50% of the grade. The other 50% is the dialogue. If I were interviewing you, I'd be looking for you to mention the space-time complexity without me prompting you. For this solution, you'd say: "The time complexity is O(n) because we traverse the string once, and the space complexity is O(min(m, n)) where m is the size of the alphabet."

I'd also be impressed if you questioned the constraints. Ask, "Is the input limited to ASCII characters?" If the answer is yes, you can replace the HashMap with a simple int[128] array. An array is significantly faster and uses less memory than a HashMap in Java because it avoids the overhead of object wrapping (Integer) and hashing collisions. Mentioning that optimization shows you aren't just memorizing LeetCode patterns—you actually understand how Java manages memory.




📋 Practical Task

Implement a Group Anagrams Logic with Array-Based Keys

You are asked to implement a method that takes an array of strings and groups anagrams together. To avoid the overhead of sorting every string (which would be O(n * k log k)), you should use a frequency array to generate a unique key for each group.

Your task: Complete the groupAnagrams method. Instead of sorting the string, create a key by counting the occurrences of each character (a-z) and formatting it as a string (e.g., "1#0#2#..." meaning one 'a', zero 'b's, two 'c's). Use a HashMap<String, List<String>> to collect the groups.

import java.util.*;

public class AnagramGrouper {
    public List<List<String>> groupAnagrams(String[] strs) {
        if (strs == null || strs.length == 0) return new ArrayList<>();
        
        Map<String, List<String>> map = new HashMap<>();
        
        for (String s : strs) {
            // TODO: Create a frequency array for 'a'-'z'
            // TODO: Convert that array into a unique String key
            // TODO: Add the string to the corresponding list in the map
        }
        
        return new ArrayList<(map.values());
    }

    public static void main(String[] args) {
        AnagramGrouper grouper = new AnagramGrouper();
        String[] input = {"eat", "tea", "tan", "ate", "nat", "bat"};
        System.out.println(grouper.groupAnagrams(input));
        // Expected output: [[eat, tea, ate], [tan, nat], [bat]]
    }
}
Rating
0 0

There are no comments for now.

to be the first to leave a comment.