Facebook Pixel

1707. Maximum XOR With an Element From Array

HardBit ManipulationTrieArray
Leetcode Link

Problem Description

You are given an array nums containing non-negative integers and a queries array where each query is represented as queries[i] = [xi, mi].

For each query i, you need to find the maximum XOR value between xi and any element in nums that is less than or equal to mi. Specifically:

  • Find all elements nums[j] where nums[j] <= mi
  • Calculate nums[j] XOR xi for each valid element
  • Return the maximum XOR value among all these calculations
  • If no element in nums satisfies nums[j] <= mi, return -1 for that query

The final result should be an array answer where answer[i] contains the result for the i-th query.

Key Points:

  • XOR operation is performed bitwise between two numbers
  • Each query has a value constraint mi that limits which elements from nums can be considered
  • The goal is to maximize the XOR result while respecting the constraint
  • Queries are independent of each other

Example Understanding: If nums = [0, 1, 2, 3, 4] and we have a query [3, 2]:

  • Valid elements from nums are those <= 2, which are [0, 1, 2]
  • Calculate XOR: 3 XOR 0 = 3, 3 XOR 1 = 2, 3 XOR 2 = 1
  • Maximum XOR value is 3, so the answer for this query is 3
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

To maximize XOR between two numbers, we want their bits to differ as much as possible, especially in the higher-order bits since they contribute more to the final value. For example, if we can make the most significant bit different, that alone gives us a value of at least 2^30 (for 31-bit numbers).

The challenge here is the constraint mi - we can only use elements from nums that don't exceed this limit. A naive approach would process each query independently by filtering valid elements and checking XOR with each one, but this would be inefficient.

The key insight is that we can process queries in a specific order to avoid redundant work. If we sort queries by their mi values in ascending order, we can incrementally add elements from nums to our data structure. Once an element is valid for a query with limit mi, it remains valid for all subsequent queries with larger limits.

This leads us to think about using a Trie (prefix tree) to store binary representations of numbers. Why a Trie? Because when finding maximum XOR, we want to greedily choose the opposite bit at each position if possible. Starting from the most significant bit, if xi has a 0 at position k, we want to find a number with 1 at that position (and vice versa).

The Trie allows us to make these greedy choices efficiently:

  • Insert numbers from nums as paths in the binary trie (each edge represents a bit: 0 or 1)
  • For each query value xi, traverse the trie by trying to take the opposite bit at each level
  • This greedy approach guarantees the maximum XOR value

By combining offline query processing (sorting queries by mi) with the binary trie structure, we can:

  1. Sort both nums and queries
  2. Process queries in order of increasing mi
  3. Incrementally add valid elements to the trie
  4. Use the trie to find maximum XOR efficiently

This way, each element is inserted into the trie exactly once, and each query is answered in O(31) time (the number of bits).

Learn more about Trie patterns.

Solution Approach

The solution uses offline query processing combined with a binary trie data structure. Here's how the implementation works:

1. Binary Trie Structure

The [Trie](/problems/trie_intro) class maintains a binary tree where each node has at most two children (representing bits 0 and 1):

  • children[0] points to the subtree for bit 0
  • children[1] points to the subtree for bit 1

Insert Operation: For each number x, we extract its bits from most significant (bit 30) to least significant (bit 0) and create a path in the trie:

def insert(self, x: int):
    node = self
    for i in range(30, -1, -1):
        v = x >> i & 1  # Extract bit at position i
        if node.children[v] is None:
            node.children[v] = Trie()
        node = node.children[v]

Search Operation: To find maximum XOR with x, we greedily try to take the opposite bit at each level:

def search(self, x: int) -> int:
    node = self
    ans = 0
    for i in range(30, -1, -1):
        v = x >> i & 1  # Current bit of x
        if node.children[v ^ 1]:  # Try opposite bit first
            ans |= 1 << i  # Set bit i in result
            node = node.children[v ^ 1]
        elif node.children[v]:  # Settle for same bit
            node = node.children[v]
        else:
            return -1  # [Trie](/problems/trie_intro) is empty

2. Offline Query Processing

Instead of processing queries in their original order, we sort them by mi values:

  1. Sort nums array: nums.sort() - This allows us to add elements incrementally
  2. Sort queries with indices: Create tuples (index, [xi, mi]) and sort by mi
  3. Process queries in sorted order:
    for i, (x, m) in sorted(zip(range(n), queries), key=lambda x: x[1][1]):

3. Incremental Trie Building

We maintain a pointer j to track which elements from nums have been inserted:

while j < len(nums) and nums[j] <= m:
    [trie](/problems/trie_intro).insert(nums[j])
    j += 1

For each query with limit m:

  • Insert all elements from nums that are <= m into the trie
  • These elements remain in the trie for subsequent queries (which have larger m values)
  • Search for maximum XOR with x using only the elements currently in the trie

4. Preserving Original Order

Since queries are processed out of order, we use the original index i to place results in the correct position:

ans = [-1] * n  # Initialize all answers to -1
for i, (x, m) in sorted(...):
    # Process query
    ans[i] = [trie](/problems/trie_intro).search(x)  # Place result at original index

Time Complexity

  • Sorting nums: O(n log n) where n = len(nums)
  • Sorting queries: O(q log q) where q = len(queries)
  • Trie operations: Each insert/search takes O(31) = O(1)
  • Total: O(n log n + q log q + (n + q) * 31) = O(n log n + q log q)

Space Complexity

  • Trie can store at most n numbers, each creating a path of length 31: O(31n) = O(n)
  • Answer array: O(q)
  • Total: O(n + q)

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a small example to illustrate the solution approach.

Input:

  • nums = [5, 2, 8, 4]
  • queries = [[3, 5], [2, 3], [7, 8]]

Step 1: Sort nums and prepare queries with indices

  • Sorted nums = [2, 4, 5, 8]
  • Queries with indices: [(0, [3, 5]), (1, [2, 3]), (2, [7, 8])]
  • Sort by mi values: [(1, [2, 3]), (0, [3, 5]), (2, [7, 8])]

Step 2: Process queries in sorted order

Initialize: j = 0, ans = [-1, -1, -1], empty Trie

Query (1, [2, 3]): xi = 2, mi = 3

  • Add elements ≀ 3 to Trie: insert 2 (binary: 010)
  • Trie now contains: 2
  • Find max XOR of 2 with Trie elements:
    • 2 (010) XOR 2 (010) = 0
  • ans[1] = 0

Query (0, [3, 5]): xi = 3, mi = 5

  • Add elements ≀ 5 to Trie: insert 4 (binary: 100) and 5 (binary: 101)
  • Trie now contains: 2, 4, 5
  • Find max XOR of 3 with Trie elements:
    • For 3 (011), traverse Trie seeking opposite bits:
      • Bit 2: 3 has 0, try 1 β†’ found (leads to 4 or 5)
      • Bit 1: 3 has 1, try 0 β†’ found (leads to 4)
      • Bit 0: 3 has 1, try 0 β†’ found (4)
    • Path gives us 4, so 3 XOR 4 = 7
  • ans[0] = 7

Query (2, [7, 8]): xi = 7, mi = 8

  • Add elements ≀ 8 to Trie: insert 8 (binary: 1000)
  • Trie now contains: 2, 4, 5, 8
  • Find max XOR of 7 with Trie elements:
    • For 7 (0111), traverse Trie seeking opposite bits:
      • Bit 3: 7 has 0, try 1 β†’ found (leads to 8)
      • Bit 2: 7 has 1, try 0 β†’ found (8)
      • Continue traversal...
    • Best path gives us 8, so 7 XOR 8 = 15
  • ans[2] = 15

Final Result: [7, 0, 15]

The key insight is that by processing queries in ascending order of mi, we can incrementally build our Trie and never need to remove elements, making the solution efficient.

Solution Implementation

1class Trie:
2    """Binary trie to store numbers and find maximum XOR"""
3    __slots__ = ["children"]
4
5    def __init__(self):
6        # Each node has two children: 0 and 1
7        self.children = [None] * 2
8
9    def insert(self, x: int) -> None:
10        """Insert a number into the trie by its binary representation"""
11        node = self
12        # Process bits from most significant to least significant (30th to 0th bit)
13        for i in range(30, -1, -1):
14            # Extract the i-th bit of x
15            bit = (x >> i) & 1
16            # Create new node if path doesn't exist
17            if node.children[bit] is None:
18                node.children[bit] = Trie()
19            # Move to the next node
20            node = node.children[bit]
21
22    def search(self, x: int) -> int:
23        """Find the maximum XOR value with x among all inserted numbers"""
24        node = self
25        max_xor = 0
26      
27        # Process bits from most significant to least significant
28        for i in range(30, -1, -1):
29            # Extract the i-th bit of x
30            bit = (x >> i) & 1
31            # Try to go opposite direction for maximum XOR
32            toggled_bit = bit ^ 1
33          
34            if node.children[toggled_bit]:
35                # If opposite bit exists, add this bit position to result
36                max_xor |= (1 << i)
37                node = node.children[toggled_bit]
38            elif node.children[bit]:
39                # If only same bit exists, follow that path
40                node = node.children[bit]
41            else:
42                # No valid path exists (trie is empty at this point)
43                return -1
44              
45        return max_xor
46
47
48class Solution:
49    def maximizeXor(self, nums: List[int], queries: List[List[int]]) -> List[int]:
50        """
51        Find maximum XOR for each query where query[i] = [xi, mi]
52        Returns max(xi XOR num) for all num in nums where num <= mi
53        """
54        trie = Trie()
55        nums.sort()  # Sort nums to process them in ascending order
56      
57        num_index = 0
58        num_queries = len(queries)
59        result = [-1] * num_queries
60      
61        # Process queries in ascending order of their limits (mi)
62        # Enumerate queries with their original indices to maintain result order
63        sorted_queries = sorted(enumerate(queries), key=lambda item: item[1][1])
64      
65        for original_index, (xi, mi) in sorted_queries:
66            # Insert all numbers <= mi into the trie
67            while num_index < len(nums) and nums[num_index] <= mi:
68                trie.insert(nums[num_index])
69                num_index += 1
70          
71            # Find maximum XOR with xi among inserted numbers
72            result[original_index] = trie.search(xi)
73          
74        return result
75
1/**
2 * Binary Trie data structure for storing integers and finding maximum XOR
3 */
4class Trie {
5    // Each node has at most 2 children (for binary digits 0 and 1)
6    private Trie[] children = new Trie[2];
7
8    /**
9     * Inserts a number into the trie by its binary representation
10     * @param x The number to insert
11     */
12    public void insert(int x) {
13        Trie currentNode = this;
14        // Process each bit from most significant (30th) to least significant (0th)
15        for (int bitPosition = 30; bitPosition >= 0; --bitPosition) {
16            // Extract the bit at current position (0 or 1)
17            int bitValue = (x >> bitPosition) & 1;
18          
19            // Create new node if path doesn't exist
20            if (currentNode.children[bitValue] == null) {
21                currentNode.children[bitValue] = new Trie();
22            }
23          
24            // Move to the child node
25            currentNode = currentNode.children[bitValue];
26        }
27    }
28
29    /**
30     * Searches for the maximum XOR value with the given number
31     * @param x The number to find maximum XOR with
32     * @return Maximum XOR value, or -1 if trie is empty
33     */
34    public int search(int x) {
35        Trie currentNode = this;
36        int maxXorValue = 0;
37      
38        // Process each bit from most significant to least significant
39        for (int bitPosition = 30; bitPosition >= 0; --bitPosition) {
40            // Extract the bit at current position
41            int bitValue = (x >> bitPosition) & 1;
42          
43            // Try to go opposite direction for maximum XOR (bitValue ^ 1)
44            if (currentNode.children[bitValue ^ 1] != null) {
45                // Set the corresponding bit in result
46                maxXorValue |= (1 << bitPosition);
47                currentNode = currentNode.children[bitValue ^ 1];
48            } 
49            // If opposite direction not available, go same direction
50            else if (currentNode.children[bitValue] != null) {
51                currentNode = currentNode.children[bitValue];
52            } 
53            // If neither path exists, trie is empty
54            else {
55                return -1;
56            }
57        }
58      
59        return maxXorValue;
60    }
61}
62
63/**
64 * Solution class for maximizing XOR with constraints
65 */
66class Solution {
67    /**
68     * For each query [xi, mi], finds the maximum XOR of xi with any element in nums <= mi
69     * @param nums Array of integers
70     * @param queries Array of queries where each query is [xi, mi]
71     * @return Array of maximum XOR values for each query
72     */
73    public int[] maximizeXor(int[] nums, int[][] queries) {
74        // Sort nums array to process elements in ascending order
75        Arrays.sort(nums);
76      
77        int queryCount = queries.length;
78      
79        // Create index array to track original query positions
80        Integer[] queryIndices = new Integer[queryCount];
81        Arrays.setAll(queryIndices, i -> i);
82      
83        // Sort queries by their limit value (mi) in ascending order
84        Arrays.sort(queryIndices, (i, j) -> queries[i][1] - queries[j][1]);
85      
86        // Initialize result array
87        int[] result = new int[queryCount];
88      
89        // Initialize trie for storing valid numbers
90        Trie trie = new Trie();
91      
92        // Pointer for nums array
93        int numsPointer = 0;
94      
95        // Process queries in sorted order by limit
96        for (int currentQueryIndex : queryIndices) {
97            int xValue = queries[currentQueryIndex][0];  // xi value
98            int limit = queries[currentQueryIndex][1];    // mi limit
99          
100            // Add all numbers <= limit to the trie
101            while (numsPointer < nums.length && nums[numsPointer] <= limit) {
102                trie.insert(nums[numsPointer]);
103                numsPointer++;
104            }
105          
106            // Find maximum XOR for current query and store at original position
107            result[currentQueryIndex] = trie.search(xValue);
108        }
109      
110        return result;
111    }
112}
113
1class Trie {
2private:
3    // Binary trie with two children (0 and 1)
4    Trie* children[2];
5
6public:
7    // Constructor initializes both children to nullptr
8    Trie() : children{nullptr, nullptr} {}
9
10    // Insert a number into the trie by its binary representation
11    void insert(int number) {
12        Trie* currentNode = this;
13      
14        // Process bits from most significant (30th) to least significant (0th)
15        for (int bitPosition = 30; bitPosition >= 0; --bitPosition) {
16            // Extract the bit at current position
17            int bitValue = (number >> bitPosition) & 1;
18          
19            // Create new node if path doesn't exist
20            if (!currentNode->children[bitValue]) {
21                currentNode->children[bitValue] = new Trie();
22            }
23          
24            // Move to the child node
25            currentNode = currentNode->children[bitValue];
26        }
27    }
28
29    // Find maximum XOR value with given number from trie
30    int search(int number) {
31        Trie* currentNode = this;
32        int maxXorValue = 0;
33      
34        // Process bits from most significant to least significant
35        for (int bitPosition = 30; bitPosition >= 0; --bitPosition) {
36            // Extract the bit at current position
37            int bitValue = (number >> bitPosition) & 1;
38          
39            // Try to go opposite direction for maximum XOR
40            if (currentNode->children[bitValue ^ 1]) {
41                // Opposite bit exists, add 1 to result at this position
42                maxXorValue |= (1 << bitPosition);
43                currentNode = currentNode->children[bitValue ^ 1];
44            } 
45            // If opposite doesn't exist, go same direction
46            else if (currentNode->children[bitValue]) {
47                currentNode = currentNode->children[bitValue];
48            } 
49            // No valid path exists (trie is empty)
50            else {
51                return -1;
52            }
53        }
54      
55        return maxXorValue;
56    }
57};
58
59class Solution {
60public:
61    vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
62        // Sort nums array in ascending order
63        sort(nums.begin(), nums.end());
64      
65        int queriesCount = queries.size();
66      
67        // Create index array for sorting queries
68        vector<int> queryIndices(queriesCount);
69        iota(queryIndices.begin(), queryIndices.end(), 0);
70      
71        // Sort query indices by their limit value (queries[i][1])
72        sort(queryIndices.begin(), queryIndices.end(), 
73             [&](int i, int j) { 
74                 return queries[i][1] < queries[j][1]; 
75             });
76      
77        // Result array to store answers
78        vector<int> result(queriesCount);
79      
80        // Initialize trie and nums pointer
81        Trie trie;
82        int numsPointer = 0;
83      
84        // Process queries in order of increasing limit
85        for (int queryIndex : queryIndices) {
86            int targetValue = queries[queryIndex][0];  // xi value
87            int limitValue = queries[queryIndex][1];   // mi limit
88          
89            // Insert all numbers <= limit into trie
90            while (numsPointer < nums.size() && nums[numsPointer] <= limitValue) {
91                trie.insert(nums[numsPointer]);
92                numsPointer++;
93            }
94          
95            // Find maximum XOR with targetValue from available numbers
96            result[queryIndex] = trie.search(targetValue);
97        }
98      
99        return result;
100    }
101};
102
1// Trie node structure for storing binary representations of numbers
2interface TrieNode {
3    children: (TrieNode | null)[];
4}
5
6// Create a new trie node with two children (for binary 0 and 1)
7function createTrieNode(): TrieNode {
8    return {
9        children: [null, null]
10    };
11}
12
13// Insert a number into the trie by its binary representation
14function insertIntoTrie(root: TrieNode, num: number): void {
15    let currentNode: TrieNode = root;
16  
17    // Process each bit from most significant to least significant (30th to 0th bit)
18    for (let bitPosition = 30; bitPosition >= 0; bitPosition--) {
19        // Extract the bit at current position
20        const bitValue = (num >> bitPosition) & 1;
21      
22        // Create new node if path doesn't exist
23        if (currentNode.children[bitValue] === null) {
24            currentNode.children[bitValue] = createTrieNode();
25        }
26      
27        // Move to the child node
28        currentNode = currentNode.children[bitValue] as TrieNode;
29    }
30}
31
32// Search for maximum XOR value with given number in the trie
33function searchMaxXorInTrie(root: TrieNode, num: number): number {
34    let currentNode: TrieNode = root;
35    let maxXorValue = 0;
36  
37    // Process each bit from most significant to least significant
38    for (let bitPosition = 30; bitPosition >= 0; bitPosition--) {
39        // Extract the bit at current position
40        const bitValue = (num >> bitPosition) & 1;
41      
42        // Try to go opposite path for maximum XOR (if bit is 0, try 1; if bit is 1, try 0)
43        const oppositeBit = bitValue ^ 1;
44      
45        if (currentNode.children[oppositeBit] !== null) {
46            // Opposite bit exists, take this path for maximum XOR
47            maxXorValue |= (1 << bitPosition);
48            currentNode = currentNode.children[oppositeBit] as TrieNode;
49        } else if (currentNode.children[bitValue] !== null) {
50            // Opposite bit doesn't exist, take the same bit path
51            currentNode = currentNode.children[bitValue] as TrieNode;
52        } else {
53            // No valid path exists (trie is empty)
54            return -1;
55        }
56    }
57  
58    return maxXorValue;
59}
60
61// Main function to maximize XOR for each query
62function maximizeXor(nums: number[], queries: number[][]): number[] {
63    // Sort nums array in ascending order
64    nums.sort((a, b) => a - b);
65  
66    const numQueries = queries.length;
67  
68    // Create indices array to sort queries by their limit value
69    const queryIndices = Array.from({ length: numQueries }, (_, index) => index);
70    queryIndices.sort((indexA, indexB) => queries[indexA][1] - queries[indexB][1]);
71  
72    // Initialize result array
73    const result: number[] = new Array(numQueries);
74  
75    // Initialize trie root
76    const trieRoot = createTrieNode();
77  
78    // Pointer for nums array
79    let numsPointer = 0;
80  
81    // Process queries in ascending order of their limit values
82    for (const queryIndex of queryIndices) {
83        const queryValue = queries[queryIndex][0];
84        const queryLimit = queries[queryIndex][1];
85      
86        // Insert all numbers less than or equal to current query limit into trie
87        while (numsPointer < nums.length && nums[numsPointer] <= queryLimit) {
88            insertIntoTrie(trieRoot, nums[numsPointer]);
89            numsPointer++;
90        }
91      
92        // Find maximum XOR for current query
93        result[queryIndex] = searchMaxXorInTrie(trieRoot, queryValue);
94    }
95  
96    return result;
97}
98

Time and Space Complexity

Time Complexity: O(n * log n + m * (log m + log M))

Breaking down the operations:

  • Sorting nums: O(n * log n) where n = len(nums)
  • Sorting queries with their indices: O(m * log m) where m = len(queries)
  • For each query:
    • Potentially insert multiple numbers into the Trie. In worst case, all n numbers are inserted across all queries, each insertion takes O(log M) time (31 bits for numbers up to 10^9)
    • Search operation in Trie: O(log M) per query
  • Total for Trie operations: O(n * log M + m * log M) = O((n + m) * log M)

Since we process each number at most once for insertion and perform one search per query, the overall time complexity is O(n * log n + m * (log m + log M)). When n is comparable to m, this can be simplified to O(m * log m + n * (log n + log M)).

Space Complexity: O(n * log M)

The space is dominated by the Trie structure:

  • Each number insertion creates at most O(log M) nodes (31 nodes for 31 bits)
  • In worst case, all n numbers are inserted into the Trie
  • Each node stores an array of size 2 for children
  • Additional space: O(m) for the answer array and O(m) for sorting queries

Therefore, the total space complexity is O(n * log M) where M ≀ 10^9.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Incorrect Bit Range Assumption

A common mistake is assuming 32-bit integers and iterating from bit 31 to 0, when the problem constraints might specify different ranges. If nums contains values up to 10^9, we only need 30 bits (since 2^30 > 10^9).

Pitfall Code:

for i in range(31, -1, -1):  # Wrong if max value is 10^9
    bit = (x >> i) & 1

Solution: Check the problem constraints and adjust the bit range accordingly:

# For values up to 10^9, use 30 bits (0-indexed from 29 to 0)
for i in range(29, -1, -1):  # Correct for max value 10^9
    bit = (x >> i) & 1

2. Not Handling Empty Trie in Search

The search function might not properly handle the case when no elements have been inserted yet (empty trie), leading to AttributeError when accessing None children.

Pitfall Code:

def search(self, x: int) -> int:
    node = self
    ans = 0
    for i in range(30, -1, -1):
        v = x >> i & 1
        # Doesn't check if both children are None
        if node.children[v ^ 1]:
            ans |= 1 << i
            node = node.children[v ^ 1]
        else:
            node = node.children[v]  # Could be None!

Solution: Add proper null checking:

def search(self, x: int) -> int:
    node = self
    ans = 0
    for i in range(30, -1, -1):
        v = x >> i & 1
        if node.children[v ^ 1]:
            ans |= 1 << i
            node = node.children[v ^ 1]
        elif node.children[v]:
            node = node.children[v]
        else:
            return -1  # No valid path exists
    return ans

3. Processing Queries in Original Order

A critical mistake is processing queries in their original order instead of sorting by mi, which defeats the purpose of offline processing and makes the solution inefficient.

Pitfall Code:

for i, (x, m) in enumerate(queries):  # Wrong! Processes in original order
    j = 0
    trie = Trie()  # Rebuilding trie for each query!
    while j < len(nums) and nums[j] <= m:
        trie.insert(nums[j])
        j += 1
    ans[i] = trie.search(x)

Solution: Sort queries by mi while preserving original indices:

# Create tuples with original indices and sort by mi
sorted_queries = sorted(enumerate(queries), key=lambda item: item[1][1])
for original_index, (xi, mi) in sorted_queries:
    # Process incrementally
    while num_index < len(nums) and nums[num_index] <= mi:
        trie.insert(nums[num_index])
        num_index += 1
    result[original_index] = trie.search(xi)

4. Resetting the Trie or Index for Each Query

Another mistake is resetting the trie or the nums index for each query, which eliminates the efficiency gain of offline processing.

Pitfall Code:

for i, (x, m) in sorted_queries:
    j = 0  # Wrong! Resets index for each query
    temp_trie = Trie()  # Wrong! Creates new trie each time
    while j < len(nums) and nums[j] <= m:
        temp_trie.insert(nums[j])
        j += 1

Solution: Maintain a single trie and index throughout:

trie = Trie()
num_index = 0  # Initialize once outside the loop
for i, (x, m) in sorted_queries:
    # Continue from where we left off
    while num_index < len(nums) and nums[num_index] <= m:
        trie.insert(nums[num_index])
        num_index += 1  # Increments persistently

5. Forgetting to Initialize Result Array with -1

The problem requires returning -1 when no valid elements exist, but forgetting to initialize the result array with -1 values can lead to incorrect outputs.

Pitfall Code:

result = [0] * num_queries  # Wrong! Should be -1 for no valid elements

Solution: Initialize with -1:

result = [-1] * num_queries  # Correct initialization
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

How would you design a stack which has a function min that returns the minimum element in the stack, in addition to push and pop? All push, pop, min should have running time O(1).


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More