Hashing is one of the most powerful ideas in Data Structures.
It allows us to trade space for time, converting many O(n²) problems into O(n) solutions.
At its core, hashing answers one question efficiently:
“Have I seen this before?”
A hash function maps a key to an index in a fixed-size table.
index = hash(key)
Example:
hash(23) = 23 % 10 = 3
Bad hash functions cause clustering, which ruins performance.
A hash table consists of:
Operations:
Average time complexity: O(1)
Worst case: O(n) (when collisions dominate)
Two different keys may produce the same hash index.
Example:
hash(12) = 2
hash(22) = 2
Each bucket stores a linked list (or tree).
Index 2 → [12 → 22 → 32]
Java uses:
Used in low-level systems, less in interviews.
hashCode() is calledImportant:
When size exceeds threshold → rehashing occurs
HashSet is internally backed by a HashMap.
HashSet.add(x) → map.put(x, PRESENT)
Properties:
Count occurrences of elements.
Example:
Find frequency of characters in a string.
Map<Character, Integer> map = new HashMap<>();
for(char c : s.toCharArray()){
map.put(c, map.getOrDefault(c, 0) + 1);
}
Used in:
Check if a subarray with sum = K exists.
O(n²)
Idea:
If
prefixSum[j] - prefixSum[i] = K
Then subarray exists.
Set<Integer> set = new HashSet<>();
set.add(0);
int sum = 0;
for(int x : arr){
sum += x;
if(set.contains(sum - K))
return true;
set.add(sum);
}
Time: O(n)
Find indices such that:
nums[i] + nums[j] = target
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
int need = target - nums[i];
if(map.containsKey(need))
return new int[]{map.get(need), i};
map.put(nums[i], i);
}
Find longest sequence of consecutive numbers.
Example:
[100, 4, 200, 1, 3, 2] → 4
num - 1 not presentSet<Integer> set = new HashSet<>();
for(int x : nums) set.add(x);
int longest = 0;
for(int x : set){
if(!set.contains(x - 1)){
int curr = x;
int count = 1;
while(set.contains(curr + 1)){
curr++;
count++;
}
longest = Math.max(longest, count);
}
}
Time: O(n)
Group words that are anagrams.
Example:
["eat","tea","tan","ate","nat","bat"]
Map<String, List<String>> map = new HashMap<>();
for(String word : strs){
char[] arr = word.toCharArray();
Arrays.sort(arr);
String key = new String(arr);
map.putIfAbsent(key, new ArrayList<>());
map.get(key).add(word);
}
class Pair {
int x, y;
public int hashCode(){
return Objects.hash(x, y);
}
public boolean equals(Object o){
Pair p = (Pair)o;
return x == p.x && y == p.y;
}
}
Without proper hashing:
Worst-case HashMap → O(n)
Reasons:
Use hashing when:
Avoid hashing when: