Hash table are primarily used to store key-value mappings, enabling efficient lookups. They exemplify a time-space tradeoff—using extra memory to reduce time complexity for search operations.
Two Sum
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Because nums[0] + nums[1] == 9.
A naive approach uses nested loops, resulting in O(n²) time complexity. Instead, a hash map can store each number’s index during traversal. For each element x, check if target - x exists in the map. If found, return the indices.
def twoSum(nums, target):
seen = {}
for idx, val in enumerate(nums):
complement = target - val
if complement in seen:
return [seen[complement], idx]
seen[val] = idx
return [-1, -1]
Group Anagrams
Input: ["eat", "tea", "tan", "ate", "nat", "bat"]
Output: [["bat"], ["nat","tan"], ["ate","eat","tea"]]
Anagrams share identical character counts. Sorting each string yields a canonical form usable as a hash key. Alternatively, a fixed-size count array (for 26 lowercase letters) can serve as a key.
from collections import defaultdict
def groupAnagrams(strs):
groups = defaultdict(list)
for s in strs:
key = ''.join(sorted(s))
groups[key].append(s)
return list(groups.values())
Longest Consecutive Sqeuence
Input: [100,4,200,1,3,2]
Output: 4 (sequence: [1,2,3,4])
Convert the array into a set for O(1) lookups. For each number, if num - 1 is not present, it's the start of a sequence. Then incrementally check for consecutive successors and track the maximum length.
def longestConsecutive(nums):
num_set = set(nums)
max_length = 0
for num in num_set:
if num - 1 not in num_set:
current = num
length = 1
while current + 1 in num_set:
current += 1
length += 1
max_length = max(max_length, length)
return max_length