What is Hashing and the Two Pointer Technique?
Solution and explanation
Hashing
Hashing maps a key to an index in an array (bucket) using a hash function, giving O(1) average-time insert, lookup and delete. Java's HashMap and HashSet are hash tables.
key "java" → hashCode() → index 3
buckets: [ ][ ][ ][ java→5 ][ ][ python→2 ][ ]
- Collisions (two keys in one bucket) are stored in a list or, in Java 8+, a balanced tree when a bucket grows large.
- When the table fills past its load factor (0.75), it resizes and rehashes.
- Worst case degrades to O(n) with a bad hash function; average stays O(1).
Map<String, Integer> count = new HashMap<>();
for (String skill : List.of("java", "sql", "java")) count.merge(skill, 1, Integer::sum);
System.out.println(count); // {java=2, sql=1}
Set<Integer> seen = new HashSet<>();
System.out.println(seen.add(5) + " " + seen.add(5)); // true false
Use hashing for counting frequencies, detecting duplicates, two-sum style lookups, grouping (anagrams) and caching.
Note: objects used as keys must implement equals() and hashCode() consistently.
Two pointer technique
Use two indices that move through the data according to a rule, often turning O(n²) pair checks into O(n).
- Opposite ends: on a sorted array, move left or right depending on the current sum (pair sum, container with most water, palindrome check).
- Same direction (slow/fast): remove duplicates in place, partition arrays, linked-list middle and cycle detection.
// Is there a pair with the target sum in a sorted array?
static boolean pairSum(int[] a, int target) {
int l = 0, r = a.length - 1;
while (l < r) {
int s = a[l] + a[r];
if (s == target) return true;
if (s < target) l++; else r--;
}
return false;
}
Complexity
- HashMap operations: O(1) average. Two pointers: O(n) time, O(1) space (after an O(n log n) sort if needed).
