3.3.10 · HinglishHashing

Applications — frequency counting, two-sum problem, caching (LRU)

2,288 words10 min readRead in English

3.3.10 · Coding › Hashing


1. Frequency Counting

WHAT chahiye: ek list di gayi ho, toh har value kitni baar aai yeh jaanna. WHY hash map: alternative (sort karo, phir runs scan karo) hai; map mein counting hai. HOW: ek pass, count[x] += 1 (missing keys ke liye default 0).


2. Two-Sum Problem

def two_sum(nums, target):
    seen = {}                       # value -> index, of elements to the LEFT
    for j, x in enumerate(nums):
        c = target - x              # the partner we need
        if c in seen:               # O(1): did it appear earlier?
            return (seen[c], j)
        seen[x] = j                 # only record AFTER checking -> avoids using x twice
    return None

3. LRU Cache (Least Recently Used)

Figure — Applications — frequency counting, two-sum problem, caching (LRU)
class Node:
    def __init__(self, k, v):
        self.k, self.v = k, v
        self.prev = self.next = None
 
class LRUCache:
    def __init__(self, capacity):
        self.cap = capacity
        self.map = {}                 # key -> Node : O(1) lookup
        self.head = Node(0, 0)        # sentinel: most-recent side
        self.tail = Node(0, 0)        # sentinel: least-recent side
        self.head.next = self.tail
        self.tail.prev = self.head
 
    def _remove(self, n):             # unlink node : O(1)
        n.prev.next = n.next
        n.next.prev = n.prev
 
    def _add_front(self, n):          # insert right after head : O(1)
        n.next = self.head.next
        n.prev = self.head
        self.head.next.prev = n
        self.head.next = n
 
    def get(self, key):
        if key not in self.map:
            return -1
        n = self.map[key]
        self._remove(n); self._add_front(n)   # touched -> now most recent
        return n.v
 
    def put(self, key, value):
        if key in self.map:
            self._remove(self.map[key])
        n = Node(key, value)
        self.map[key] = n
        self._add_front(n)
        if len(self.map) > self.cap:          # over capacity -> evict
            lru = self.tail.prev              # node just before tail = least recent
            self._remove(lru)
            del self.map[lru.k]

Recall Feynman: ek 12-saal ke bachche ko samjhao

Socho ek magic notebook hai jahan tum instantly kisi bhi naam par flip kar sakte ho aur uske saath ek number dekh sakte ho. Counting: jab bhi tum koi dost dekho uske naam ke saath 1 add karo — end mein pata chalega kaun sabse zyada aaya. Two-Sum: tum chahte ho do cards jo 10 tak add hon; har card ke liye check karo "kya maine pehle se 10-minus-yeh card dekha?" — notebook instantly jawab deti hai. LRU: tumhara toy box sirf 2 toys fit karta hai; jo toy tumne sabse haal mein kheli woh top par rakhte ho, aur jab naya toy aata hai tum woh toy phenkh dete ho jo sabse neeche thi aur jise tum sabse zyada ignore karte the. Notebook instantly batati hai har toy kahan hai.

Flashcards

Frequency map kya store karta hai?
key → kitni baar woh key appear hui; ek pass mein build hoti hai.
n items aur k distinct ke saath frequency counting ka time aur space?
Time , Space (worst ).
Two-Sum mein x ka "complement" kya hai?
; woh partner value jo target tak pahunchne ke liye chahiye.
Hash-map Two-Sum kyun hai brute ke muqable mein?
Har index ek complement lookup karta hai, baad ke saare elements scan karne ki jagah.
Two-Sum mein complement check karne ke BAAD seen mein insert kyun karte hain?
Ek element ko apne aap se match hone se bachane ke liye (ek element do baar use ho jaata).
Kyun ek plain hash map akele LRU cache implement nahi kar sakta?
Usmein recency order nahi hai, toh least-recently-used key dhundna ho jaega.
LRU cache banane ke liye kaun se do data structures combine hote hain?
Ek hash map (key→node) aur ek doubly linked list recency ke order mein.
LRU ke liye doubly (singly nahi) linked list kyun?
Kisi arbitrary node ko mein unlink karne ke liye predecessor pointer (prev) chahiye.
LRU list mein kaun sa end evict hota hai aur kyun?
Back (tail sentinel se thoda pehle) — woh least recently used hota hai.
Successful get par LRU node ke saath kya karta hai?
Use remove karta hai aur front par re-add karta hai (use most recently used mark karta hai).
Frequency counting ke liye hash map ki jagah array kab better hoti hai?
Jab keys small, dense integers hon (e.g. 26 lowercase letters).
In applications mein hashing ka general trade-off kya hai?
Memory trade karo ( table) average-time lookups ke liye.

Connections

  • Hash Functions average lookup jo teeno apps ko power deta hai
  • Collision Resolution (Chaining vs Open Addressing) — kyun "average" hai, worst-case nahi
  • Doubly Linked List — LRU mein recency ordering engine
  • Sliding Window — frequency maps ke saath aksar pair hota hai (anagrams, longest substring)
  • Time Complexity Analysis vs vs comparisons
  • Caching Strategies — LRU vs LFU vs FIFO eviction policies

Concept Map

enables

enables

enables

core tradeoff

map key to count

one pass

two-pass use

map value to index

need target minus x

beats brute force

map key to node

Hash Map O1 lookup

Frequency Counting

Two-Sum

LRU Cache

Trade memory for time

Frequency Map

O of n time

First non-repeating char

Complement trick

Invariant seen holds prior indices

O of n vs O of n squared

Least-recently-used victim