Sign Up Sign Up


Have an account? Sign In Now

Sign In Sign In


Forgot Password?

Don't have account, Sign Up Here

Forgot Password Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.


Have an account? Sign In Now

You must login to ask a question.


Forgot Password?

Need An Account, Sign Up Here

You must login to add post.


Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

RTSALL Logo RTSALL Logo
Sign InSign Up

RTSALL

RTSALL Navigation

  • Home
  • Tools
    • Run Code
    • JSON Beautifier
    • Regex Tester
    • Diff Checker
    • JWT Decoder
    • UUID Generator
    • .htaccess Generator
    • YAML/JSON Converter
    • SQL Formatter
    • Cron Generator
    • JSON to CSV/Excel
    • System Design Estimator
  • DSA
    • All DSA Problems
    • Online C++ Runner
    • Arrays, Strings & Cache
    • Two Pointers & Sliding Window
    • Linked Lists & Custom Allocators
    • Stacks, Queues & Ring Buffers
    • Trees, BSTs & Indexes
    • Tries & Prefix Search
    • Heaps & Priority Schedulers
    • Hashing & Collision Resolution
    • Graphs & Network Topologies
    • Dynamic Programming
    • Advanced Bitmask & Tree DP
    • Greedy & Resource Allocation
    • Binary Search & State Spaces
    • Bit Manipulation & Low-Level
    • System-Scale & Probabilistic
  • AI Utilities
    • Token Counter
    • JSON Schema Compiler
    • Fine-Tuning JSONL Converter
    • Vector RAG Playground
    • Prompt Optimizer & Architect
    • LLM GPU VRAM Calculator
  • Finance Tools
    • Compound Interest Calculator
    • Simple Interest Calculator
    • Present Value (PV) Calculator
    • Future Value (FV) Calculator
    • NPV Calculator
    • IRR Calculator
    • CAGR Calculator
    • Dividend Income Calculator
    • Yield on Cost Calculator
    • Dividend Payout Ratio
    • WACC Calculator
    • CAPM & Cost of Equity
    • Cost of Debt Calculator
    • DCF Valuation Calculator
    • Enterprise Value Calculator
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Tools
    • Run Code
    • JSON Beautifier
    • Regex Tester
    • Diff Checker
    • JWT Decoder
    • UUID Generator
    • .htaccess Generator
    • YAML/JSON Converter
    • SQL Formatter
    • Cron Generator
    • JSON to CSV/Excel
    • System Design Estimator
  • DSA
    • All DSA Problems
    • Online C++ Runner
    • Arrays, Strings & Cache
    • Two Pointers & Sliding Window
    • Linked Lists & Custom Allocators
    • Stacks, Queues & Ring Buffers
    • Trees, BSTs & Indexes
    • Tries & Prefix Search
    • Heaps & Priority Schedulers
    • Hashing & Collision Resolution
    • Graphs & Network Topologies
    • Dynamic Programming
    • Advanced Bitmask & Tree DP
    • Greedy & Resource Allocation
    • Binary Search & State Spaces
    • Bit Manipulation & Low-Level
    • System-Scale & Probabilistic
  • AI Utilities
    • Token Counter
    • JSON Schema Compiler
    • Fine-Tuning JSONL Converter
    • Vector RAG Playground
    • Prompt Optimizer & Architect
    • LLM GPU VRAM Calculator
  • Finance Tools
    • Compound Interest Calculator
    • Simple Interest Calculator
    • Present Value (PV) Calculator
    • Future Value (FV) Calculator
    • NPV Calculator
    • IRR Calculator
    • CAGR Calculator
    • Dividend Income Calculator
    • Yield on Cost Calculator
    • Dividend Payout Ratio
    • WACC Calculator
    • CAPM & Cost of Equity
    • Cost of Debt Calculator
    • DCF Valuation Calculator
    • Enterprise Value Calculator
  • About Us
  • Blog
  • Contact Us

Data Structures & Algorithms

Master core and advanced data structures and algorithms with production-grade implementations, hardware-conscious optimizations, and real-world system designs.

Share
  • Facebook
0 Followers
54 Answers
30 Questions
Home/Data Structures & Algorithms/Page 2
  • Recent Questions
  • Most Answered
  • Answers
  • No Answers
  • Most Visited
  • Most Voted
  • Random
  1. Asked: September 11, 2026In: Data Structures & Algorithms, System-Scale & Probabilistic Structures

    How does a Fenwick Tree (Binary Indexed Tree) query and update prefix sums in O(log N) using i & (-i)?

    Abhay Tiwari
    Abhay Tiwari Begginer
    Added an answer on September 11, 2026 at 9:53 am

    The Fenwick Tree (invented by Peter Fenwick in 1994) is one of the most compact data structures ever devised. It gives you the full power of a dynamic segment tree in just one flat array of size N with 10 lines of code. 1. The Secret: Powers of 2 Range Decomposition Any positive integer can be uniquRead more

    The Fenwick Tree (invented by Peter Fenwick in 1994) is one of the most compact data structures ever devised. It gives you the full power of a dynamic segment tree in just one flat array of size N with 10 lines of code.

    1. The Secret: Powers of 2 Range Decomposition

    Any positive integer can be uniquely represented as a sum of powers of 2. For example: 13 = 8 + 4 + 1.

    Fenwick took this idea and applied it to prefix ranges: instead of storing every single element, tree[i] stores the sum of a contiguous range of length equal to its lowest set bit!

    The length of the range responsible by index i is given by: lowbit(i) = i & (-i).

    • If i = 12 (1100_2): lowbit(12) = 4. So tree[12] stores the sum of 4 elements: indices [9, 10, 11, 12]!
    • If i = 8 (1000_2): lowbit(8) = 8. So tree[8] stores the sum of the first 8 elements: [1 ... 8]!

    2. The Two Operations

    A. Prefix Sum Query: `i -= (i & -i)`

    To calculate the prefix sum up to index 13:

    1. Read tree[13] (covers index 13). 13 - lowbit(13) = 13 - 1 = 12.
    2. Read tree[12] (covers indices 9 through 12). 12 - lowbit(12) = 12 - 4 = 8.
    3. Read tree[8] (covers indices 1 through 8). 8 - lowbit(8) = 8 - 8 = 0 (Done!).

    Total reads: only 3 steps to sum 13 numbers! At each step, you strip off one binary bit, taking at most O(log N) operations.

    B. Point Update: `i += (i & -i)`

    When you add delta to element i, which parent ranges need to be updated? Every index whose range covers i! You navigate up the tree simply by adding the lowest set bit: i += (i & -i)!


    Clean C++20 Implementation

    #include <vector>
    #include <cstdint>
    
    class FenwickTree {
        std::vector<int64_t> tree;
        int n;
    
        static inline int lowbit(int x) {
            return x & (-x);
        }
    
    public:
        FenwickTree(int size) : n(size), tree(size + 1, 0) {}
    
        // Adds delta to index i (1-indexed) in O(log N)
        void update(int i, int64_t delta) {
            while (i <= n) {
                tree[i] += delta;
                i += lowbit(i);
            }
        }
    
        // Computes sum of prefix [1 ... i] in O(log N)
        int64_t query(int i) const {
            int64_t sum = 0;
            while (i > 0) {
                sum += tree[i];
                i -= lowbit(i);
            }
            return sum;
        }
    
        // Computes range sum [l ... r] in O(log N)
        int64_t queryRange(int l, int r) const {
            if (l > r) return 0;
            return query(r) - query(l - 1);
        }
    };
    

    Why Fenwick Beats Segment Trees in Production

    MetricSegment TreeFenwick Tree
    Memory Overhead4N (or 2N)Strictly 1N (4x smaller)
    Implementation Size50-80 lines15 lines
    L1 Cache PerformanceModerateBlazing Fast (flat contiguous array)
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  2. Asked: September 11, 2026In: Data Structures & Algorithms, Graphs & Network Topologies

    Topological Sort: Kahn’s Algorithm (BFS) vs Tarjan’s DFS in massive dependency graphs

    Anonymous
    Anonymous Begginer
    Added an answer on September 11, 2026 at 9:53 am

    In software build graphs and task schedulers, Kahn's Algorithm (Indegree BFS) is universally favored over recursive DFS for two huge reasons: No Recursion / Call-Stack Exhaustion: DFS recursion on a graph with 500,000 chained dependencies will instantly crash with a stack overflow (RecursionError orRead more

    In software build graphs and task schedulers, Kahn’s Algorithm (Indegree BFS) is universally favored over recursive DFS for two huge reasons:

    1. No Recursion / Call-Stack Exhaustion: DFS recursion on a graph with 500,000 chained dependencies will instantly crash with a stack overflow (RecursionError or OS segfault). Kahn’s algorithm runs iteratively using a queue in heap memory.
    2. Trivial Cycle Detection: With DFS, cycle detection requires tracking 3 node states (Unvisited, Visiting, Visited). With Kahn’s algorithm, cycle detection is automatic: if the number of sorted nodes is less than total nodes, a cycle exists!

    The Plain English Mental Model of Kahn’s Algorithm

    Think about taking university courses. A course with indegree = 0 has zero prerequisites—you can enroll in it on Day 1!

    1. Count the indegree (number of incoming dependency arrows) for every single node.
    2. Find all nodes with indegree == 0 and push them into a queue (these tasks can run immediately).
    3. While the queue is not empty:
      • Pop a task u and add it to your execution plan.
      • For every task v that depended on u, decrement its indegree (indegree[v]--).
      • If indegree[v] == 0, all its prerequisites are now satisfied! Push it into the queue!

    If there was a circular dependency (e.g., A depends on B and B depends on A), their indegrees will never reach 0, so they will never enter the queue!


    Clean Python 3.12 Implementation

    from collections import deque
    
    def find_order(num_courses: int, prerequisites: list[list[int]]) -> list[int]:
        """Returns topological execution order in O(V + E) time, or [] if cycle detected."""
        adj = [[] for _ in range(num_courses)]
        indegree = [0] * num_courses
    
        # Build adjacency list: [prereq -> course]
        for dest, src in prerequisites:
            adj[src].append(dest)
            indegree[dest] += 1
    
        # Initialize queue with all nodes having 0 prerequisites
        queue = deque([i for i in range(num_courses) if indegree[i] == 0])
        order = []
    
        while queue:
            u = queue.popleft()
            order.append(u)
    
            for v in adj[u]:
                indegree[v] -= 1
                if indegree[v] == 0:
                    queue.append(v)
    
        # If order doesn't contain all courses, a cyclic dependency exists!
        if len(order) != num_courses:
            return []
    
        return order
    

    Complexity Breakdown

    • Time Complexity: O(V + E). We touch every vertex and edge exactly once.
    • Space Complexity: O(V + E) to store the adjacency list and indegree table.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  3. Asked: September 11, 2026In: Data Structures & Algorithms, Linked Lists & Custom Allocators

    Floyd’s Tortoise and Hare: Mathematical proof of why meeting point resolves cycle origin

    Abhay Tiwari
    Abhay Tiwari Begginer
    Added an answer on September 11, 2026 at 9:53 am

    Floyd's cycle algorithm is pure mathematical poetry. Let's write out the distances with simple algebra so the proof is crystal clear. 1. Defining the Variables Let's map out the linked list into three distinct segments: L: Distance from the head to the cycle entrance. C: Total length (circumference)Read more

    Floyd’s cycle algorithm is pure mathematical poetry. Let’s write out the distances with simple algebra so the proof is crystal clear.

    1. Defining the Variables

    Let’s map out the linked list into three distinct segments:

    • L: Distance from the head to the cycle entrance.
    • C: Total length (circumference) of the cycle.
    • x: Distance from the cycle entrance to the meeting point inside the cycle.

    2. Distance Traveled by Each Pointer

    When the Tortoise (slow) and Hare (fast) meet:

    • Slow moved: Dist_slow = L + x
    • Fast moved: Dist_fast = L + n * C + x (where n is how many full laps fast ran around the cycle).

    Because the fast pointer moves at twice the speed of slow:

    Dist_fast = 2 * Dist_slow
    L + n * C + x = 2 * (L + x)
    L + n * C + x = 2L + 2x
    

    Now subtract L + x from both sides:

    n * C = L + x
    L = n * C - x
    L = (n - 1) * C + (C - x)
    

    3. What does L = (n – 1) * C + (C – x) mean?

    Look carefully at that equation:

    • L is the distance from head to the cycle entrance.
    • (C - x) is the distance from the meeting point to the cycle entrance!
    • (n - 1) * C is just zero or more full loops around the cycle!

    Conclusion: If you place Pointer 1 at head (which must travel distance L) and Pointer 2 at meeting_point (which travels distance (C - x) plus some optional full laps), both pointers will meet at the EXACT same node: the cycle entrance!


    Clean Python 3.12 Implementation

    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    
    def detect_cycle_entry(head: ListNode | None) -> ListNode | None:
        """Finds the node where cycle begins in O(N) time and O(1) space."""
        if not head or not head.next:
            return None
    
        slow = head
        fast = head
    
        # Phase 1: Determine if a cycle exists
        has_cycle = False
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                has_cycle = True
                break
    
        if not has_cycle:
            return None
    
        # Phase 2: Find cycle entrance
        ptr1 = head
        ptr2 = slow
        while ptr1 != ptr2:
            ptr1 = ptr1.next
            ptr2 = ptr2.next
    
        return ptr1
    

    Complexity Breakdown

    • Time Complexity: O(N). Phase 1 takes at most $2N$ steps. Phase 2 takes at most $N$ steps.
    • Space Complexity: O(1). No hash set or memory allocation.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  4. Asked: September 11, 2026In: Arrays, Strings & Cache Memory, Data Structures & Algorithms

    How does the Dutch National Flag 3-way partition work in a single pass with zero branch mispredictions?

    Abhay Tiwari
    Abhay Tiwari Begginer
    Added an answer on September 11, 2026 at 9:53 am

    The Dutch National Flag algorithm (invented by Edsger W. Dijkstra) is the secret weapon that makes 3-way QuickSort resilient against duplicate keys. 1. The 3 Pointer Invariant We divide the array into 4 distinct regions using 3 pointers: low, mid, and high: [ 0 ... low-1 ] -> All elements strictlRead more

    The Dutch National Flag algorithm (invented by Edsger W. Dijkstra) is the secret weapon that makes 3-way QuickSort resilient against duplicate keys.

    1. The 3 Pointer Invariant

    We divide the array into 4 distinct regions using 3 pointers: low, mid, and high:

    [ 0 ... low-1 ]  -> All elements strictly 0
    [ low ... mid-1 ] -> All elements strictly 1
    [ mid ... high ]  -> UNKNOWN (yet to be inspected)
    [ high+1 ... n-1] -> All elements strictly 2
    

    Initially, low = 0, mid = 0, and high = n - 1. The entire array is initially inside the UNKNOWN region.


    2. The 3 State Transitions

    While mid <= high, inspect nums[mid]:

    1. If nums[mid] == 0: Swap nums[low] with nums[mid]. Increment BOTH low++ and mid++.
      Why can we increment mid here? Because whatever was sitting at low was already processed (it was guaranteed to be a 1).
    2. If nums[mid] == 1: It’s already in the right spot! Just increment mid++.
    3. If nums[mid] == 2: Swap nums[mid] with nums[high]. Decrement high--.
      THE CRITICAL CATCH: Do NOT increment mid here! Whatever came from high was unknown—it might be a 0, a 1, or another 2! We must inspect it on the next loop iteration!

    Clean Python 3.12 Implementation

    def sort_colors(nums: list[int]) -> None:
        """In-place 3-way partition in O(N) time and O(1) memory."""
        low = 0
        mid = 0
        high = len(nums) - 1
    
        while mid <= high:
            if nums[mid] == 0:
                nums[low], nums[mid] = nums[mid], nums[low]
                low += 1
                mid += 1
            elif nums[mid] == 1:
                mid += 1
            else: # nums[mid] == 2
                nums[mid], nums[high] = nums[high], nums[mid]
                high -= 1
                # Note: mid is intentionally NOT incremented here!
    

    Complexity Breakdown

    • Time Complexity: O(N). In every single step, either mid increases or high decreases. The unknown window (high - mid) strictly shrinks to zero in at most N steps.
    • Space Complexity: O(1). No extra memory allocated.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  5. Asked: September 11, 2026In: Advanced DP: Bitmask & Tree DP, Data Structures & Algorithms

    Traveling Salesperson Problem: How does Bitmask DP reduce (N – 1)! factorial to O(N^2 * 2^N)?

    Anonymous
    Anonymous Begginer
    Added an answer on September 11, 2026 at 9:52 am

    The Held-Karp Bitmask DP algorithm is the premier textbook demonstration of converting a factorial combinatorial explosion into a manageable exponential dynamic programming state space. 1. The Core Insight (Subproblem Overlap) Suppose a drone visits cities in the order: 1 → 2 → 3 → 4.Read more

    The Held-Karp Bitmask DP algorithm is the premier textbook demonstration of converting a factorial combinatorial explosion into a manageable exponential dynamic programming state space.

    1. The Core Insight (Subproblem Overlap)

    Suppose a drone visits cities in the order: 1 → 2 → 3 → 4.

    Another candidate path visits cities in the order: 1 → 3 → 2 → 4.

    Notice that in both cases, the set of visited cities is identical ({1, 2, 3, 4}), and the current ending city is identical (City 4)!

    For future route choices (visiting the remaining cities 5 through 20), it does not matter how you traveled between 1, 2, and 3—all that matters is what is the minimum cost to have visited that exact subset and currently be sitting at City 4!


    2. The State Definition

    We define our DP state with two parameters: dp(mask, u)

    • mask: An integer whose binary bits represent the subset of visited cities. If bit i is 1, City i has been visited. If bit i is 0, City i is unvisited.
    • u: The current city where the drone is currently parked.

    Transition:

    To move to an unvisited city v (where (mask & (1 << v)) == 0):

    dp(mask | (1 << v), v) = min(
        dp(mask | (1 << v), v),
        dp(mask, u) + dist[u][v]
    )
    

    Clean Python 3.12 Implementation with Memoization

    from functools import lru_cache
    
    def tsp(dist: list[list[int]]) -> int:
        n = len(dist)
        ALL_VISITED = (1 << n) - 1
    
        @lru_cache(maxsize=None)
        def solve(mask: int, curr: int) -> int:
            # Base case: All cities have been visited -> return to starting city 0
            if mask == ALL_VISITED:
                return dist[curr][0]
    
            min_cost = float('inf')
    
            # Try visiting every unvisited city
            for nxt in range(n):
                if not (mask & (1 << nxt)):
                    cost = dist[curr][nxt] + solve(mask | (1 << nxt), nxt)
                    min_cost = min(min_cost, cost)
    
            return min_cost
    
        # Start at city 0 with only bit 0 set (1 << 0 = 1)
        return solve(1, 0)
    

    Complexity Breakdown: From 10^17 down to 10^7

    • Total Distinct States: $2^N$ masks $ imes N$ current cities = $N cdot 2^N$.
    • Work per State: Loop over $N$ candidate next cities.
    • Total Time Complexity: $O(N^2 cdot 2^N)$.

    For $N = 20$:

    • Brute force $19! pprox 1.21 imes 10^{17}$ operations (would take 3,800 years at 1 GHz).
    • Held-Karp $20^2 cdot 2^{20} = 400 imes 1,048,576 pprox 4.19 imes 10^8$ operations (runs in under 1.5 seconds on a modern CPU)!
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  6. Asked: September 11, 2026In: Data Structures & Algorithms, System-Scale & Probabilistic Structures

    How does a Count-Min Sketch estimate heavy-hitter item frequencies under bounded RAM?

    Abhay Tiwari
    Abhay Tiwari Begginer
    Added an answer on September 11, 2026 at 9:52 am

    The Count-Min Sketch (CMS) is the gold-standard probabilistic algorithm for tracking frequencies in massive, unconstrained data streams (used extensively in Apache Spark, network switches, and Google search analytics). 1. Architectural Layout A Count-Min Sketch consists of a 2D matrix of integer couRead more

    The Count-Min Sketch (CMS) is the gold-standard probabilistic algorithm for tracking frequencies in massive, unconstrained data streams (used extensively in Apache Spark, network switches, and Google search analytics).

    1. Architectural Layout

    A Count-Min Sketch consists of a 2D matrix of integer counters with d rows (depth) and w columns (width), paired with d independent hash functions:

    Row 0: [0, 0, 0, 0, ..., 0]  <--- Hash Function h_0(x)
    Row 1: [0, 0, 0, 0, ..., 0]  <--- Hash Function h_1(x)
    ...
    Row d: [0, 0, 0, 0, ..., 0]  <--- Hash Function h_d(x)
    

    2. The Operations

    A. Add Item `x` (Increment):

    For each row i from 0 to d - 1, compute column index col = h_i(x) % w, and increment that counter:

    table[i][h_i(x) % w] += 1
    

    B. Query Frequency of `x` (Point Query):

    Because multiple items might collide at the same counter bucket, hash collisions can only increase a counter, never decrease it!

    Therefore, to get the best possible estimate, we take the MINIMUM across all d rows:

    estimated_count = min(table[i][h_i(x) % w] for i in range(d))
    

    The Golden Invariant: A Count-Min Sketch NEVER underestimates the true count! True frequency is always $le$ estimated frequency.


    3. Mathematical Dimensioning Rules

    If you want an error bound within $epsilon cdot N$ with confidence probability $1 – delta$:

    • Width: $w = lceil rac{e}{epsilon}
      ceil pprox lceil rac{2.718}{epsilon}
      ceil$
    • Depth: $d = lceil ln( rac{1}{delta})
      ceil$

    For example, to guarantee $le 0.1%$ error with $99%$ confidence, you need only $w = 2718$ columns and $d = 5$ rows. That’s just 13,590 integer counters (~54 KB of RAM) to monitor billions of events!


    Clean Python 3.12 Implementation

    import math
    import mmh3 # MurmurHash3
    
    class CountMinSketch:
        def __init__(self, epsilon: float = 0.001, delta: float = 0.01):
            self.w = int(math.ceil(math.e / epsilon))
            self.d = int(math.ceil(math.log(1.0 / delta)))
            self.table = [[0] * self.w for _ in range(self.d)]
    
        def add(self, item: str, count: int = 1) -> None:
            """Increments counter for item across all d hash functions."""
            for row in range(self.d):
                col = mmh3.hash(item, row, signed=False) % self.w
                self.table[row][col] += count
    
        def query(self, item: str) -> int:
            """Returns minimum count across all d rows (never underestimates)."""
            return min(
                self.table[row][mmh3.hash(item, row, signed=False) % self.w]
                for row in range(self.d)
            )
    

    Complexity Breakdown

    • Add Time: O(d) — strictly constant time ($5$ hash calculations and memory writes).
    • Query Time: O(d) — strictly constant time ($5$ lookups).
    • Memory Footprint: O(w * d) — strictly fixed in size. Bounded memory that never grows regardless of how many billions of packets arrive!
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  7. Asked: September 11, 2026In: Data Structures & Algorithms, Hashing & Collision Resolution

    How to implement Consistent Hashing with Virtual Nodes to eliminate hot spots in distributed caches?

    Anonymous
    Anonymous Begginer
    Added an answer on September 11, 2026 at 9:52 am

    Consistent Hashing is one of the foundational building blocks of distributed systems (used in Apache Cassandra, Amazon DynamoDB, Akamai CDN, and Envoy Proxy). 1. The Problem with Naive Modulo Hashing If you have 4 servers and use hash(key) % 4, when server 4 crashes, you now compute hash(key) % 3. BRead more

    Consistent Hashing is one of the foundational building blocks of distributed systems (used in Apache Cassandra, Amazon DynamoDB, Akamai CDN, and Envoy Proxy).

    1. The Problem with Naive Modulo Hashing

    If you have 4 servers and use hash(key) % 4, when server 4 crashes, you now compute hash(key) % 3. Because almost every number changes its remainder modulo 3, nearly 100% of cached keys instantly miss, hammering your backend database in a catastrophic thundering herd.

    In Consistent Hashing, when a server is added or removed, only $1/N$ of keys need to be remapped on average. All other keys stay on their existing servers!


    2. The Hash Ring & Why Virtual Nodes are Mandatory

    Imagine a circular ring of numbers from $0$ to $2^{32} – 1$ (the output space of a 32-bit hash function like Murmur3 or MD5).

    • Each physical server is hashed onto a point on this ring.
    • To find where a key belongs, you hash the key, find its coordinate on the ring, and walk clockwise until you hit the first server!

    The Hot Spot Problem: If you only place 3 physical servers on the ring, their hash positions might be clustered close together (e.g. at 10 degrees, 25 degrees, and 280 degrees). Server 3 will end up handling 70% of all traffic, causing a massive hot spot!

    The Solution (Virtual Nodes): Instead of hashing Server A once, we hash it 100 or 200 times under different labels ("server-A#1", "server-A#2", …, "server-A#200"). By distributing hundreds of virtual replicas uniformly across the 360-degree ring, standard deviations drop to near zero, and load is balanced evenly across all physical hardware.


    Production Python 3.12 Implementation with bisect

    import bisect
    import hashlib
    
    class ConsistentHashRing:
        def __init__(self, replicas: int = 150):
            self.replicas = replicas  # Virtual nodes per physical server
            self.ring: list[int] = [] # Sorted list of virtual node hash keys
            self.node_map: dict[int, str] = {} # hash_key -> physical_node_id
    
        def _hash(self, key: str) -> int:
            """Returns 32-bit integer hash using MD5."""
            return int(hashlib.md5(key.encode('utf-8')).hexdigest()[:8], 16)
    
        def add_node(self, node: str) -> None:
            """Adds a physical node by creating virtual replicas across the ring."""
            for i in range(self.replicas):
                v_key = f"{node}#vn_{i}"
                h = self._hash(v_key)
                idx = bisect.bisect_left(self.ring, h)
                self.ring.insert(idx, h)
                self.node_map[h] = node
    
        def remove_node(self, node: str) -> None:
            """Removes all virtual replicas belonging to the physical node."""
            for i in range(self.replicas):
                v_key = f"{node}#vn_{i}"
                h = self._hash(v_key)
                idx = bisect.bisect_left(self.ring, h)
                if idx < len(self.ring) and self.ring[idx] == h:
                    self.ring.pop(idx)
                    del self.node_map[h]
    
        def get_node(self, key: str) -> str | None:
            """Finds the physical server responsible for the given key in O(log(V * N))."""
            if not self.ring:
                return None
    
            h = self._hash(key)
            # Binary search clockwise to the nearest virtual node
            idx = bisect.bisect_right(self.ring, h)
            
            # If we walked past the end of the ring, wrap around to index 0
            if idx == len(self.ring):
                idx = 0
    
            return self.node_map[self.ring[idx]]
    

    Complexity Breakdown

    • Key Lookup: O(log(R * N)) using binary search, where R is replicas (e.g. 150) and N is physical servers (e.g. 10). Searching an array of 1,500 numbers takes 11 comparisons (< 1 microsecond).
    • Node Add/Remove: O(R * log(R * N)). Adding a server only migrates keys from its immediate clockwise neighbor!
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  8. Asked: September 11, 2026In: Data Structures & Algorithms, Greedy & Resource Allocation

    Gas Station Circular Tour: Mathematical proof of why a single pass in O(N) is sufficient

    Anonymous
    Anonymous Begginer
    Added an answer on September 11, 2026 at 9:52 am

    The Gas Station problem is one of the most elegant examples of the Greedy Elimination Proof. Let's break down the mathematical invariant that allows you to skip stations with 100% confidence. 1. The Two Fundamental Theorems Theorem 1: Total Balance Invariant If $sum gas[i] ge sum cost[i]$, there isRead more

    The Gas Station problem is one of the most elegant examples of the Greedy Elimination Proof. Let’s break down the mathematical invariant that allows you to skip stations with 100% confidence.

    1. The Two Fundamental Theorems

    Theorem 1: Total Balance Invariant

    If $sum gas[i] ge sum cost[i]$, there is guaranteed to be at least one valid starting station that completes the entire circuit.

    Why? Because the total net balance $sum (gas[i] – cost[i]) ge 0$. If you graph the cumulative fuel sum along the circle, the lowest dip (the absolute minimum point on the graph) is the optimal starting point! Starting right after that lowest dip means your tank will never dip below zero!

    Theorem 2: The Greedy Skip Invariant

    Suppose you start at station A and successfully reach station B, but you fail to travel from B to B + 1 (your tank drops below 0).

    Claim: No station C between A and B (i.e. $A le C le B$) can be the starting station!

    Proof:

    1. Because you started at A and reached C, the gas you had in your tank upon arriving at C was $ge 0$.
    2. Even with that bonus leftover gas from before C, you still starved and died at B!
    3. If you were to start at C from scratch (with an empty tank, zero bonus gas), you would run out of fuel at or before station B!

    Therefore, every single station from A to B is mathematically disqualified in one fell swoop! The next possible candidate can only be B + 1.


    Clean Python 3.12 Implementation

    def can_complete_circuit(gas: list[int], cost: list[int]) -> int:
        """Finds starting gas station index in single pass O(N) time."""
        total_tank = 0
        curr_tank = 0
        starting_station = 0
    
        for i in range(len(gas)):
            diff = gas[i] - cost[i]
            total_tank += diff
            curr_tank += diff
    
            # If we run out of gas at station i
            if curr_tank < 0:
                # Pick the next station as candidate start
                starting_station = i + 1
                # Reset current tank to 0
                curr_tank = 0
    
        # If total gas is less than total cost, impossible to complete circle
        return starting_station if total_tank >= 0 else -1
    

    Complexity Breakdown

    • Time Complexity: O(N). Exactly one single pass through the array. Zero nested loops.
    • Space Complexity: O(1). Exactly 3 scalar integers tracking running totals.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  9. Asked: September 11, 2026In: Data Structures & Algorithms, Tries & Prefix Search Engines

    How does a 32-bit Binary Trie find the Maximum XOR of Two Numbers in O(N) time?

    Abhay Tiwari
    Abhay Tiwari Begginer
    Added an answer on September 11, 2026 at 9:52 am

    The Maximum XOR problem is the ultimate showcase of how bit manipulation and trees blend together. Once you see the greedy nature of binary numbers, the Binary Trie solution becomes second nature. 1. The Greedy Bit Principle In binary numbers, the Most Significant Bit (MSB) has more numerical valueRead more

    The Maximum XOR problem is the ultimate showcase of how bit manipulation and trees blend together. Once you see the greedy nature of binary numbers, the Binary Trie solution becomes second nature.

    1. The Greedy Bit Principle

    In binary numbers, the Most Significant Bit (MSB) has more numerical value than all lower bits combined! For example, bit 30 ($2^{30} pprox 1.07 imes 10^9$) is strictly greater than the sum of all bits from 0 to 29 combined ($2^{30} – 1$).

    Therefore, to maximize an XOR sum, you must be greedy from left to right (MSB down to LSB):

    • If the current bit of number num is 1, you desperately want to pair it with a number whose corresponding bit is 0 (because 1 ^ 0 = 1).
    • If the current bit of num is 0, you want to pair it with a number whose corresponding bit is 1 (because 0 ^ 1 = 1).

    2. Why a Binary Trie?

    A Binary Trie is just a tree where every node has at most two children: 0 (left) and 1 (right).

    1. Insert: You insert each number into the Trie as a 31-bit or 32-bit string of binary digits, from bit 31 down to bit 0.
    2. Query: For each number x, you walk down the Trie. At each bit b, you ask: ‘Does the opposite branch (1 - b) exist?’
      • If YES: Take that branch! That bit in your XOR result becomes 1.
      • If NO: You’re forced to take the same branch (b), so that bit in your XOR result becomes 0.

    Because you made the best possible choice at every single bit position starting from the highest power of 2, the final accumulated number is mathematically guaranteed to be the global maximum XOR!


    Clean Python 3.12 Implementation

    class TrieNode:
        __slots__ = ('children',)
        def __init__(self):
            self.children: list[TrieNode | None] = [None, None]
    
    class Solution:
        def find_maximum_xor(self, nums: list[int]) -> int:
            root = TrieNode()
    
            # Step 1: Insert all numbers into the 31-bit binary trie
            for num in nums:
                curr = root
                for i in range(30, -1, -1):
                    bit = (num >> i) & 1
                    if not curr.children[bit]:
                        curr.children[bit] = TrieNode()
                    curr = curr.children[bit]
    
            # Step 2: Query each number against the trie
            max_xor = 0
            for num in nums:
                curr = root
                current_xor = 0
                for i in range(30, -1, -1):
                    bit = (num >> i) & 1
                    opposite_bit = 1 - bit
                    
                    # Greedily check if the complementary bit exists
                    if curr.children[opposite_bit]:
                        current_xor |= (1 << i)
                        curr = curr.children[opposite_bit]
                    else:
                        curr = curr.children[bit]
                        
                max_xor = max(max_xor, current_xor)
    
            return max_xor
    

    Complexity Breakdown

    • Time Complexity: O(31 * N) = O(N). Inserting N numbers takes 31 * N operations. Querying N numbers takes 31 * N operations. Total time is strictly linear in the number of elements.
    • Space Complexity: O(31 * N) worst-case node allocations. In practice, prefix branches overlap heavily, keeping memory around a few megabytes.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  10. Asked: September 11, 2026In: Bit Manipulation & Low-Level Computing, Data Structures & Algorithms

    How does Brian Kernighan’s bit algorithm work, and why does n & (n – 1) clear the lowest set bit?

    Abhay Tiwari
    Abhay Tiwari Begginer
    Added an answer on September 11, 2026 at 9:52 am

    The trick n & (n - 1) is one of the most elegant one-liners in computer engineering. Let's look at the exact bitwise mechanics so the mathematical proof becomes obvious. 1. What happens when you subtract 1 in binary? Think about standard base-10 math: when you subtract 1 from 1000, what happens?Read more

    The trick n & (n - 1) is one of the most elegant one-liners in computer engineering. Let’s look at the exact bitwise mechanics so the mathematical proof becomes obvious.

    1. What happens when you subtract 1 in binary?

    Think about standard base-10 math: when you subtract 1 from 1000, what happens? The lowest non-zero digit (1) becomes 0, and all trailing zeroes become 9s: 0999.

    Binary works exactly the same way, but with 0s and 1s:

    Any positive binary integer can be written in this general form:

    n = (arbitrary prefix) 1 0 0 0 ... 0
    

    where the 1 shown is the lowest set bit (the rightmost 1), followed by zero or more 0s.

    When you compute n - 1:

    1. The arbitrary prefix before the lowest 1 remains completely untouched.
    2. That lowest 1 turns into a 0 (borrowing from the subtraction).
    3. All the trailing 0s flip into 1s!
        n     = (prefix) 1 0 0 0
      n - 1   = (prefix) 0 1 1 1
    

    2. The Bitwise AND Operation: n & (n – 1)

    Now perform a bitwise AND between n and n - 1:

        n     = (prefix) 1 0 0 0
    & n - 1   = (prefix) 0 1 1 1
    ----------------------------
      result  = (prefix) 0 0 0 0
    

    Look at what happened:

    • The prefix matched identically → remains preserved.
    • The rightmost 1 was paired with 0 → becomes 0!
    • The trailing 0s were paired with 1s → remain 0!

    Conclusion: The operation n & (n - 1) turns off the lowest set bit in n and leaves every other bit completely unchanged. Pure mathematical magic!


    3. Real-World Applications

    A. Counting Set Bits in O(k) time (where k is number of 1s)

    Instead of looping 32 or 64 times, Brian Kernighan’s algorithm loops only as many times as there are 1-bits:

    def count_set_bits(n: int) -> int:
        count = 0
        while n > 0:
            n &= (n - 1)  # Strips off one set bit per loop iteration
            count += 1
        return count
    

    If a 64-bit integer has only two set bits, this loop executes exactly twice and terminates!

    B. Instant Power of Two Check in O(1)

    A power of two in binary has exactly one set bit (e.g. 8 = 1000_2, 16 = 10000_2). If you strip that single bit and the result is 0, it was a power of 2:

    def is_power_of_two(n: int) -> bool:
        return n > 0 and (n & (n - 1)) == 0
    

    C. Hardware POPCNT Alternative

    On modern x86_64 CPUs, you have the dedicated hardware assembly instruction POPCNT (or __builtin_popcount in GCC/Clang), which computes set bits in a single CPU cycle. But when writing portable code or kernel routines without AVX/SSE guarantees, Brian Kernighan’s algorithm remains the golden standard.

    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
Load More Answers

Sidebar

Ask A Question
  • Popular
  • Answers
  • Queryiest

    What is a database?

    • 3 Answers
  • Anonymous

    How to rotate an array in-place with O(1) space and ...

    • 3 Answers
  • hannah

    What steps can businesses take to identify the most valuable ...

    • 2 Answers
  • Vikram
    aarav0 added an answer Direct Technical Solution: Unlike IVFFlat (which partitions vector spaces with… September 11, 2026 at 9:57 pm
  • Abhishek
    Abhishek added an answer Direct Technical Solution: In C++20, range view adaptors (like std::views::filter,… September 11, 2026 at 9:57 pm
  • Sneha Patel
    Anonymous added an answer Direct Technical Solution: torch.cuda.empty_cache() releases only cached (unallocated) blocks back… September 11, 2026 at 9:57 pm

Top Members

Queryiest

Queryiest

  • 201 Questions
  • 295 Points
Enlightened
Anonymous

Anonymous

  • 11 Questions
  • 42 Points
Begginer
paperubofficial

paperubofficial

  • 0 Questions
  • 22 Points
Begginer

Trending Tags

ai asp.net aws basics aws certification aws console aws free tier aws login aws scenario-based questions c++ career cyber security cyber security interview git java javascript jobs jquery net core net core interview questions sql

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • DSA Problems
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • New Questions
  • Trending Questions
  • Must read Questions
  • Hot Questions

Footer

About Us

  • Meet The Team
  • Blog
  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy
  • Disclaimer
  • Terms & Conditions

Help

  • Knowledge Base
  • Support

Follow

© 2023-25 RTSALL. All Rights Reserved