Common Map Patterns

Pattern 1: Frequency Counter

Track how often each element appears.

def most_frequent(nums):
    freq = {}
    max_count = 0
    result = None

    for num in nums:
        freq[num] = freq.get(num, 0) + 1
        if freq[num] > max_count:
            max_count = freq[num]
            result = num

    return result

nums = [1, 3, 2, 3, 3, 1, 3]
print(most_frequent(nums))  # 3

With Counter

from collections import Counter

def top_k_frequent(nums, k):
    freq = Counter(nums)
    return [num for num, count in freq.most_common(k)]

nums = [1, 1, 1, 2, 2, 3]
print(top_k_frequent(nums, 2))  # [1, 2]

Pattern 2: Index Mapping

Map values to their positions.

def two_sum(nums, target):
    """Find indices of two numbers that sum to target"""
    seen = {}  # num -> index

    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i

    return []

nums = [2, 7, 11, 15]
print(two_sum(nums, 9))  # [0, 1]

Pattern 3: Multiple Values per Key

Group related items together.

from collections import defaultdict

def group_shifted_strings(strings):
    """Group strings that are shifts of each other"""
    groups = defaultdict(list)

    for s in strings:
        # Create key based on shift pattern
        key = tuple((ord(s[i+1]) - ord(s[i])) % 26
                    for i in range(len(s) - 1))
        groups[key].append(s)

    return list(groups.values())

strings = ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"]
print(group_shifted_strings(strings))
# [['abc', 'bcd', 'xyz'], ['acef'], ['az', 'ba'], ['a', 'z']]

Pattern 4: Complement Lookup

Find pairs that satisfy a condition.

def find_pairs(nums, k):
    """Count pairs with difference k"""
    num_set = set(nums)
    count = 0

    for num in num_set:
        if num + k in num_set:
            count += 1

    return count

nums = [1, 3, 1, 5, 4]
print(find_pairs(nums, 2))  # 3: (1,3), (3,5), (3,1)

Pattern 5: Running Sum/Product

Track cumulative values for subarray problems.

def subarray_sum(nums, k):
    """Count subarrays with sum equal to k"""
    prefix_sums = {0: 1}  # sum -> count
    current_sum = 0
    count = 0

    for num in nums:
        current_sum += num

        # Check if (current_sum - k) exists
        if current_sum - k in prefix_sums:
            count += prefix_sums[current_sum - k]

        # Update prefix sum count
        prefix_sums[current_sum] = prefix_sums.get(current_sum, 0) + 1

    return count

nums = [1, 1, 1]
print(subarray_sum(nums, 2))  # 2: [1,1] appears twice

Pattern 6: State Tracking

Remember what you've seen and make decisions.

def can_construct(ransom_note, magazine):
    """Can we build ransom note from magazine letters?"""
    available = {}

    # Count available letters
    for char in magazine:
        available[char] = available.get(char, 0) + 1

    # Try to use letters
    for char in ransom_note:
        if available.get(char, 0) == 0:
            return False
        available[char] -= 1

    return True

print(can_construct("aa", "aab"))    # True
print(can_construct("aa", "ab"))     # False

Pattern 7: Coordinate/Position Mapping

Map coordinates to values for grid problems.

def is_path_crossing(path):
    """Does path cross itself?"""
    x, y = 0, 0
    visited = {(0, 0)}

    moves = {'N': (0, 1), 'S': (0, -1),
             'E': (1, 0), 'W': (-1, 0)}

    for direction in path:
        dx, dy = moves[direction]
        x, y = x + dx, y + dy

        if (x, y) in visited:
            return True
        visited.add((x, y))

    return False

print(is_path_crossing("NES"))   # False
print(is_path_crossing("NESWW")) # True

Pattern 8: First Unique Element

Track order and frequency simultaneously.

def first_unique_char(s):
    """Find first non-repeating character"""
    freq = {}

    # Count frequencies
    for char in s:
        freq[char] = freq.get(char, 0) + 1

    # Find first with frequency 1
    for i, char in enumerate(s):
        if freq[char] == 1:
            return i

    return -1

print(first_unique_char("leetcode"))    # 0 ('l')
print(first_unique_char("loveleetcode")) # 2 ('v')

Pattern 9: Longest/Shortest Sequence

Track boundaries or lengths.

def longest_substring_without_repeating(s):
    """Find length of longest substring without repeating chars"""
    char_index = {}
    max_length = 0
    start = 0

    for end, char in enumerate(s):
        # If char seen and in current window
        if char in char_index and char_index[char] >= start:
            start = char_index[char] + 1

        char_index[char] = end
        max_length = max(max_length, end - start + 1)

    return max_length

print(longest_substring_without_repeating("abcabcbb"))  # 3 ("abc")
print(longest_substring_without_repeating("bbbbb"))     # 1 ("b")

Pattern 10: Graph as Adjacency Map

Represent graph relationships.

def build_graph(edges):
    """Build adjacency list from edges"""
    graph = defaultdict(list)

    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)  # For undirected

    return graph

edges = [(1, 2), (1, 3), (2, 4)]
graph = build_graph(edges)
print(dict(graph))
# {1: [2, 3], 2: [1, 4], 3: [1], 4: [2]}

Summary of Patterns

  1. Frequency Counter: Count occurrences
  2. Index Mapping: Remember positions
  3. Grouping: Collect related items
  4. Complement Lookup: Find matching pairs
  5. Prefix Sums: Track running totals
  6. State Tracking: Remember what you've seen
  7. Coordinate Mapping: Position-based storage
  8. Order + Frequency: Track both simultaneously
  9. Window Tracking: Sliding window problems
  10. Graph Representation: Adjacency lists