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 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

Abhay Tiwari

Begginer
Ask Abhay Tiwari
0 Visits
2 Followers
5 Questions
Home/Abhay Tiwari/Answers
  • About
  • Questions
  • Polls
  • Answers
  • Best Answers
  • Followed
  • Favorites
  • Asked Questions
  • Groups
  • Joined Groups
  • Managed Groups
  1. 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
  2. Asked: September 11, 2026In: Data Structures & Algorithms, Dynamic Programming: 1D, 2D & Grid

    Why does Patience Sorting solve Longest Increasing Subsequence in O(N log N) instead of O(N^2)?

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

    This is one of the most common points of confusion when studying LIS. Let's clear up the mystery of why the tails array works even though its contents look 'wrong'. 1. What does the `tails` array actually represent? In Patience Sorting (inspired by solitaire card games): tails[k] stores the SMALLESTRead more

    This is one of the most common points of confusion when studying LIS. Let’s clear up the mystery of why the tails array works even though its contents look ‘wrong’.

    1. What does the `tails` array actually represent?

    In Patience Sorting (inspired by solitaire card games):

    tails[k] stores the SMALLEST ending value of an increasing subsequence of length k + 1 found so far.

    Why do we care about the smallest ending value? Because in an increasing subsequence, the smaller the number you end with, the easier it is for future numbers to be bigger than it! You want to keep your options as open as possible.


    2. The Step-by-Step Card Dealing Analogy

    Suppose our array is: [10, 9, 2, 5, 3, 7, 101, 18].

    1. See 10: tails = [10] (Best subsequence of len 1 ends with 10).
    2. See 9: 9 < 10. Replace 10 with 9: tails = [9] (Ending with 9 is strictly better than ending with 10).
    3. See 2: 2 < 9. Replace 9 with 2: tails = [2].
    4. See 5: 5 > 2! Extend! tails = [2, 5] (Best len 1 ends in 2, best len 2 ends in 5).
    5. See 3: 3 < 5. Replace 5 with 3: tails = [2, 3] (Now best len 2 ends in 3!).
    6. See 7: 7 > 3! Extend! tails = [2, 3, 7] (Len 3).
    7. See 101: Extend! tails = [2, 3, 7, 101] (Len 4).
    8. See 18: 18 < 101. Replace 101 with 18: tails = [2, 3, 7, 18].

    Total length of tails is 4. The answer is 4!


    3. Why the array contents might look scrambled, but length is ALWAYS correct

    Imagine if after [2, 3, 7, 18] we saw 1. We would replace 2 with 1, resulting in tails = [1, 3, 7, 18].

    Notice that [1, 3, 7, 18] might not be a valid subsequence from the original array. And that doesn’t matter!

    Replacing 2 with 1 only prepares the board for a hypothetical future subsequence that starts with 1. It does not change the fact that a valid subsequence of length 4 ([2, 3, 7, 18]) was already locked in!

    The length of tails only increases when a number is strictly greater than ALL existing tail values. Replacements never shrink the array length!


    Clean Python 3.12 Implementation with bisect_left

    from bisect import bisect_left
    
    def length_of_lis(nums: list[int]) -> int:
        """Calculates length of LIS in O(N log N) time and O(N) space."""
        tails = []
    
        for x in nums:
            # Binary search: find first element in tails >= x
            idx = bisect_left(tails, x)
            
            if idx == len(tails):
                # x is strictly greater than all existing tails -> extend length!
                tails.append(x)
            else:
                # Found smaller tail candidate -> update in-place
                tails[idx] = x
    
        return len(tails)
    

    Complexity Breakdown

    • Time Complexity: O(N log N). We iterate through N elements, and for each element we perform binary search over tails (at most length N). N * log(N). For 100,000 elements, this finishes in 0.02 seconds (compared to ~45 seconds for O(N^2)).
    • Space Complexity: O(N) to hold the tails array.
    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, Trees, BSTs & Hierarchical Indexes

    How to traverse a Binary Tree in O(1) memory without recursion or stack (Morris Traversal)?

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

    Morris Traversal is one of the most brilliant algorithms in computer science. It solves the exact constraint you're facing: how do you traverse a tree without spending any extra memory on a stack? 1. The Core Secret: Threaded Binary Trees When you are at a node and go deep into its left subtree, howRead more

    Morris Traversal is one of the most brilliant algorithms in computer science. It solves the exact constraint you’re facing: how do you traverse a tree without spending any extra memory on a stack?

    1. The Core Secret: Threaded Binary Trees

    When you are at a node and go deep into its left subtree, how do you get back up to the node without a parent pointer or call stack? Normally, you need a stack to remember the return path.

    J. H. Morris realized something clever: in every binary tree, about half of all pointers are NULL! Every leaf node has a null right child that is sitting there doing nothing.

    Morris repurposes these unused null pointers as temporary bridge wires (called “threads”) back to the inorder successor:

    1. Find the node’s inorder predecessor (the rightmost node in the left subtree).
    2. If its right pointer is null, point it back to the current node: predecessor->right = current. Then move current = current->left.
    3. If its right pointer is already pointing to current, that means you have already finished visiting the left subtree! You print/record current->val, restore the pointer to null (repairing the tree), and move current = current->right!

    When the algorithm finishes, the tree is 100% restored to its original state. Zero memory allocated, zero permanent mutations!


    Clean C++20 Morris Inorder Traversal

    #include <vector>
    #include <cstdint>
    
    struct TreeNode {
        int val;
        TreeNode* left;
        TreeNode* right;
        TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };
    
    std::vector<int> morrisInorderTraversal(TreeNode* root) {
        std::vector<int> result;
        TreeNode* curr = root;
    
        while (curr != nullptr) {
            if (curr->left == nullptr) {
                // Case 1: No left child, visit this node and move right
                result.push_back(curr->val);
                curr = curr->right;
            } else {
                // Case 2: Find inorder predecessor (rightmost in left subtree)
                TreeNode* pred = curr->left;
                while (pred->right != nullptr && pred->right != curr) {
                    pred = pred->right;
                }
    
                if (pred->right == nullptr) {
                    // First time visiting: create temporary thread
                    pred->right = curr;
                    curr = curr->left;
                } else {
                    // Second time visiting: restore tree and visit curr
                    pred->right = nullptr;
                    result.push_back(curr->val);
                    curr = curr->right;
                }
            }
        }
        return result;
    }
    

    Complexity & Trade-offs

    • Time Complexity: O(N). Even though we search for predecessors, each edge in the tree is traversed at most 3 times (once to find predecessor, once to create thread, once to remove thread). 3 * (N - 1) = O(N).
    • Space Complexity: O(1) auxiliary space. Just two pointers (curr and pred). No call stack, no heap allocations.
    • Thread-Safety Warning: Because Morris Traversal temporarily mutates right pointers during execution, it is not safe for concurrent readers on the same tree instance. If multiple threads read the tree simultaneously, use standard recursive DFS with a large stack or an explicit thread-local queue.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  4. Asked: September 11, 2026In: Binary Search & Monotonic Spaces, Data Structures & Algorithms

    Binary Search on Answer: How to solve Koko Eating Bananas without floating-point bugs?

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

    Binary Search on Answer Space is one of the highest-leverage algorithmic patterns you can learn. Once you recognize it, dozens of seemingly hard problems (shipping packages, splitting arrays, cutting ribbons, allocating memory) all collapse into the exact same 15 lines of code. 1. When Can You Use TRead more

    Binary Search on Answer Space is one of the highest-leverage algorithmic patterns you can learn. Once you recognize it, dozens of seemingly hard problems (shipping packages, splitting arrays, cutting ribbons, allocating memory) all collapse into the exact same 15 lines of code.

    1. When Can You Use This Pattern?

    Ask yourself one simple question: Is the condition monotonic?

    • If Koko eats at speed k = 100 bananas/hour and succeeds in finishing in under h hours, would eating at speed k = 101 also succeed? Yes, always.
    • If eating at speed k = 5 is too slow and fails, would eating at speed k = 4 also fail? Yes, always.

    Because the outcome transitions cleanly from False, False, ..., True, True, True, the answer space is monotonic. That means we don’t need to test every speed from 1 to 1 billion linearly—we can binary search it in O(log(MaxPile)) steps!


    2. The Integer Ceiling Trick (Say Goodbye to Float Bugs)

    If Koko has a pile of 7 bananas and eats at speed k = 3, she needs ceil(7 / 3) = 3 hours.

    In Python or C++, doing math.ceil(pile / k) converts the numbers to IEEE-754 64-bit floats. On massive numbers (e.g. 10^14), floating-point precision degrades, causing silent off-by-one errors.

    The standard integer arithmetic replacement for ceil(a / b) is:

    hours = (pile + k - 1) // k
    

    Let’s test it: (7 + 3 - 1) // 3 = 9 // 3 = 3. Exactly right, 100% integer math, zero float conversions!


    3. Clean Python 3.12 Implementation

    from typing import Sequence
    
    def min_eating_speed(piles: Sequence[int], h: int) -> int:
        """Finds minimum integer eating speed k such that total hours <= h."""
        
        # Lower bound: Koko must eat at least 1 banana per hour
        # Upper bound: Eating faster than the largest pile doesn't save any more time
        low = 1
        high = max(piles)
        ans = high
    
        def can_finish(speed: int) -> bool:
            total_hours = 0
            for pile in piles:
                # Equivalent to ceil(pile / speed) without floats
                total_hours += (pile + speed - 1) // speed
                if total_hours > h:
                    return False  # Early exit optimization
            return total_hours <= h
    
        while low <= high:
            mid = low + (high - low) // 2
            
            if can_finish(mid):
                ans = mid         # mid is valid, but can we go even slower?
                high = mid - 1    # try searching left
            else:
                low = mid + 1     # too slow, must eat faster
    
        return ans
    

    4. Complexity & Production Benchmarks

    • Time Complexity: O(N * log(M)) where N is the number of piles and M is max(piles). If M = 10^9, log2(10^9) ≈ 30. Even with 100,000 piles, the validation function runs at most 30 times. Total operations: ~3 million, executing in under 15 milliseconds.
    • Space Complexity: O(1) auxiliary memory.
    • Overflow Note for C++ / Java: In C++, total_hours can easily exceed 2^31 - 1 if speeds are small and piles are large. Always declare int64_t total_hours = 0; to prevent integer overflow.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  5. Asked: September 11, 2026In: Data Structures & Algorithms, Stacks, Queues & Ring Buffers

    How does a Monotonic Stack solve Largest Rectangle in Histogram in a single pass?

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

    The Largest Rectangle in Histogram is famous because it feels like magic until you see the visual geometry behind it. Let's demystify it once and for all. 1. The Core Realization For any bar at index k with height H = heights[k], what is the widest rectangle you can make using H as the height? The rRead more

    The Largest Rectangle in Histogram is famous because it feels like magic until you see the visual geometry behind it. Let’s demystify it once and for all.

    1. The Core Realization

    For any bar at index k with height H = heights[k], what is the widest rectangle you can make using H as the height?

    The rectangle can extend as far left as possible until it hits a bar shorter than H, and as far right as possible until it hits another bar shorter than H.

    So the entire problem boils down to finding two things for every bar:

    1. The First Shorter Bar on the Left (left boundary).
    2. The First Shorter Bar on the Right (right boundary).

    2. Why a Monotonic Increasing Stack?

    A monotonic stack keeps indices of bars whose heights are strictly increasing: [2, 4, 6, 8].

    As long as the next bar is taller or equal, the rectangle could potentially keep growing, so we just push its index onto the stack.

    The Trigger: The moment you encounter a bar that is shorter than the top of the stack (say we see a bar of height 3 when the stack top is 8), you have found the Right Boundary for that 8! The bar of height 8 cannot extend any further to the right. Its journey is finished.

    When you pop 8:

    • The current index i is its first shorter bar on the right.
    • The new top of the stack (the element directly below it) is its first shorter bar on the left!

    Therefore, the width of the rectangle bounded by height H is simply: width = (i - stack[-1] - 1).


    3. Clean Python 3.12 Implementation with Sentinel Trick

    def largest_rectangle_area(heights: list[int]) -> int:
        """Calculates maximum rectangular area in histogram in O(N) time."""
        # Appending 0 at the end acts as a sentinel that forces
        # all remaining bars in the stack to be popped and calculated!
        extended_heights = heights + [0]
        stack: list[int] = []  # Stores indices
        max_area = 0
    
        for i, h in enumerate(extended_heights):
            # While the current bar is shorter than the bar at stack top
            while stack and extended_heights[stack[-1]] > h:
                height = extended_heights[stack.pop()]
                
                # If stack is empty, it means 'height' was shorter than everything to its left!
                width = i if not stack else i - stack[-1] - 1
                max_area = max(max_area, height * width)
                
            stack.append(i)
    
        return max_area
    

    4. Step-by-Step Trace with Numbers

    Let’s trace heights = [2, 1, 5, 6, 2, 3] with sentinel [2, 1, 5, 6, 2, 3, 0]:

    • i = 0 (h=2): Stack = [0]
    • i = 1 (h=1): 1 < 2! Pop 0 (h=2). Stack empty → width = 1. Area = 2 * 1 = 2. Push 1. Stack = [1].
    • i = 2 (h=5): 5 > 1. Push 2. Stack = [1, 2].
    • i = 3 (h=6): 6 > 5. Push 3. Stack = [1, 2, 3].
    • i = 4 (h=2): 2 < 6!
      • Pop 3 (h=6): right = 4, left = 2 → width = 4 - 2 - 1 = 1. Area = 6 * 1 = 6.
      • Pop 2 (h=5): right = 4, left = 1 → width = 4 - 1 - 1 = 2. Area = 5 * 2 = 10!

      Push 4. Stack = [1, 4].

    • Finally, the trailing 0 sentinel cleanly flushes all remaining elements.

    Max Area = 10 (from bars of height 5 and 6).


    5. Why is this strictly O(N)?

    Even though there is a while loop inside the for loop, every index is pushed onto the stack exactly once and popped from the stack at most once. Total operations across the entire array are at most 2N. That is a rock-solid, linear O(N) runtime with O(N) memory.

    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, Two Pointers & Sliding Window

    Why does the Two-Pointer approach beat Monotonic Stack for Trapping Rainwater in production?

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

    I see this question come up all the time in engineering interviews and production optimizations. The short answer is: memory allocations and CPU cache locality. On paper, both the Monotonic Stack and Two Pointers are O(N) time. But in reality: Monotonic Stack: Pushes and pops indices into a dynamicRead more

    I see this question come up all the time in engineering interviews and production optimizations. The short answer is: memory allocations and CPU cache locality.

    On paper, both the Monotonic Stack and Two Pointers are O(N) time. But in reality:

    • Monotonic Stack: Pushes and pops indices into a dynamic stack (like std::stack in C++ or a dynamic slice in Python/Go). That means repeated memory allocations, pointer indirection, and cache misses every time the stack resizes or wanders through heap memory.
    • Two-Pointer Approach: Uses just 4 integer variables (left, right, left_max, right_max). These variables stay entirely inside CPU registers. There is zero heap allocation, zero pointer chasing, and the CPU prefetcher streams the array from both ends sequentially at full hardware bus speed.

    The Plain English Intuition

    Think about standing at the edge of a swimming pool. The amount of water that can sit on top of any single column i is strictly decided by one thing: the shorter of the two tallest walls on its left and right.

    Mathematically: water[i] = max(0, min(max_left, max_right) - height[i]).

    Here is the genius of two pointers: you place one pointer at the start (left) and one at the end (right). At every step:

    1. If height[left] <= height[right], you know for certain that whatever tall wall exists on the far right is at least as tall as height[left]. So the bottleneck for the left side is only determined by left_max. You can safely calculate water at left and move left++.
    2. If height[right] < height[left], the exact opposite holds true. The bottleneck for right is determined purely by right_max. You calculate water at right and move right--.

    You never have to look back, and you never have to store past heights in a stack!


    Production-Ready Python 3.12 Implementation

    from typing import Sequence
    
    def trap_rain_water(height: Sequence[int]) -> int:
        """Calculates total trapped water in O(N) time and O(1) extra space."""
        if len(height) < 3:
            return 0
    
        left, right = 0, len(height) - 1
        left_max, right_max = 0, 0
        total_water = 0
    
        while left < right:
            if height[left] <= height[right]:
                if height[left] >= left_max:
                    left_max = height[left]  # New wall found, no water trapped here
                else:
                    total_water += left_max - height[left]
                left += 1
            else:
                if height[right] >= right_max:
                    right_max = height[right] # New wall found on right
                else:
                    total_water += right_max - height[right]
                right -= 1
    
        return total_water
    

    Clean C++20 Version (Zero Allocations)

    #include <vector>
    #include <cstdint>
    
    int64_t trap(const std::vector<int32_t>& height) noexcept {
        const size_t n = height.size();
        if (n < 3) return 0;
    
        size_t left = 0;
        size_t right = n - 1;
        int32_t left_max = 0;
        int32_t right_max = 0;
        int64_t total_water = 0;
    
        while (left < right) {
            if (height[left] <= height[right]) {
                if (height[left] >= left_max) {
                    left_max = height[left];
                } else {
                    total_water += (left_max - height[left]);
                }
                ++left;
            } else {
                if (height[right] >= right_max) {
                    right_max = height[right];
                } else {
                    total_water += (right_max - height[right]);
                }
                --right;
            }
        }
        return total_water;
    }
    

    Complexity & Production Pitfalls

    • Time Complexity: O(N). Every element is visited exactly once. No nested loops.
    • Space Complexity: O(1). No auxiliary memory allocated.
    • 32-bit Integer Overflow: If you have an array of 100,000 elements, each with height 100,000, the total water can reach 10^10. A standard 32-bit signed integer will overflow and return a negative number! Always use a 64-bit integer (int64_t in C++ or long in Java) for the accumulator.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
  7. Asked: September 11, 2026In: Arrays, Strings & Cache Memory, Data Structures & Algorithms

    How to rotate an array in-place with O(1) space and zero cache misses?

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

    This is a classic problem where the textbook solution and the production solution diverge. When you are moving 10 million integers in memory, allocating a temp slice or doing naive cyclic swaps will kill your performance due to cache misses. The cleanest, most battle-tested way to do this in productRead more

    This is a classic problem where the textbook solution and the production solution diverge. When you are moving 10 million integers in memory, allocating a temp slice or doing naive cyclic swaps will kill your performance due to cache misses.

    The cleanest, most battle-tested way to do this in production is the 3-Reversal Trick (often called the Reversal Algorithm). It requires zero extra memory and traverses contiguous memory sequentially, which modern CPU prefetchers love.

    1. The Intuition (Why 3 Reversals Work)

    Suppose you have the array [1, 2, 3, 4, 5, 6, 7] and you want to rotate right by k = 3 (so [5, 6, 7, 1, 2, 3, 4]).

    Notice the split: the last k elements need to move to the front, and the first n - k elements move to the back. If you reverse the whole thing first, everything is in the right neighborhood but backwards:

    1. Reverse the entire array: [7, 6, 5, 4, 3, 2, 1]
    2. Reverse the first k elements (0 to k-1): [5, 6, 7, 4, 3, 2, 1]
    3. Reverse the remaining n-k elements (k to n-1): [5, 6, 7, 1, 2, 3, 4]

    Done! Every element is now in its exact final position.


    2. Production C++20 Implementation

    #include <vector>
    #include <algorithm>
    #include <cstdint>
    
    // In-place rotation using standard cache-friendly iterator reversal
    void rotateArrayInPlace(std::vector<int32_t>& nums, size_t k) {
        const size_t n = nums.size();
        if (n <= 1) return;
        
        // Normalize k in case k > n
        k = k % n;
        if (k == 0) return;
    
        // Helper lambda for two-pointer swap
        auto reverseRange = [&nums](size_t start, size_t end) {
            while (start < end) {
                std::swap(nums[start], nums[end]);
                ++start;
                --end;
            }
        };
    
        // 1. Flip everything
        reverseRange(0, n - 1);
        // 2. Flip the first k
        reverseRange(0, k - 1);
        // 3. Flip the rest
        reverseRange(k, n - 1);
    }
    

    3. Python 3.12 Clean Version

    def rotate_in_place(nums: list[int], k: int) -> None:
        """Rotates nums to the right by k steps in-place with O(1) extra space."""
        n = len(nums)
        if n <= 1:
            return
        k = k % n
        if k == 0:
            return
    
        def reverse(start: int, end: int) -> None:
            while start < end:
                nums[start], nums[end] = nums[end], nums[start]
                start += 1
                end -= 1
    
        # Step 1: reverse full list
        reverse(0, n - 1)
        # Step 2: reverse first k elements
        reverse(0, k - 1)
        # Step 3: reverse remaining elements
        reverse(k, n - 1)
    

    4. Complexity Breakdown

    • Time Complexity: O(N) total time. Step 1 does n/2 swaps, Step 2 does k/2 swaps, and Step 3 does (n-k)/2 swaps. Total swaps = exactly n swaps. You can't beat linear time because every element must change position.
    • Space Complexity: O(1) auxiliary space. Just two index pointers living directly in CPU registers.
    • Cache Friendliness: Because the pointers move inward in contiguous linear blocks, L1/L2 cache prefetching works at full hardware memory bandwidth.

    5. Real-World Gotchas to Watch Out For

    • When k > n: Always take k = k % n. Forgetting this causes out-of-bounds pointer crashes when k = 15 on an array of length 5.
    • Negative k (Left Rotation): If your system asks for a left rotation by k, simply transform it: a left rotation by k is equivalent to a right rotation by (n - (k % n)) % n.
    • Empty or Single Element Arrays: Check n <= 1 upfront to prevent unsigned integer underflow on n - 1.
    See less
    • 0
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
1 2

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