Approach
Sorting and greedy selection
For Maximum XOR With an Element From Array, the implementation first exposes a useful order, then scans that order while making locally justified choices.
- Choose the key that reveals the greedy or grouping structure.
- Sort the relevant records by that key.
- Scan in order, maintaining the invariant that makes each local choice safe.
Code notes
- 85 lines of C++ from the credited upstream file 1707.cpp.
- The implementation visibly relies on sequence storage.
- 5 loop blocks detected.
Complexity
Sorting is typically the dominant term unless the subsequent scan uses a more expensive nested operation.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1struct TrieNode {2 vector<shared_ptr<TrieNode>> children;3 TrieNode() : children(2) {}4};5 6class BitTrie {7 public:8 BitTrie(int maxBit) : maxBit(maxBit) {}9 10 void insert(int num) {11 shared_ptr<TrieNode> node = root;12 for (int i = maxBit; i >= 0; --i) {13 const int bit = num >> i & 1;14 if (node->children[bit] == nullptr)15 node->children[bit] = make_shared<TrieNode>();16 node = node->children[bit];17 }18 }19 20 int getMaxXor(int num) {21 int maxXor = 0;22 shared_ptr<TrieNode> node = root;23 for (int i = maxBit; i >= 0; --i) {24 const int bit = num >> i & 1;25 const int toggleBit = bit ^ 1;26 if (node->children[toggleBit] != nullptr) {27 maxXor = maxXor | 1 << i;28 node = node->children[toggleBit];29 } else if (node->children[bit] != nullptr) {30 node = node->children[bit];31 } else { 32 return 0;33 }34 }35 return maxXor;36 }37 38 private:39 const int maxBit;40 shared_ptr<TrieNode> root = make_shared<TrieNode>();41};42 43struct IndexedQuery {44 int queryIndex;45 int x;46 int m;47};48 49class Solution {50 public:51 vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {52 vector<int> ans(queries.size(), -1);53 const int maxNumInNums = ranges::max(nums);54 const int maxNumInQuery = ranges::max_element(queries, ranges::less{},55 [](const vector<int>& query) {56 return query[0];57 })->at(0);58 const int maxBit = static_cast<int>(log2(max(maxNumInNums, maxNumInQuery)));59 BitTrie bitTrie(maxBit);60 61 ranges::sort(nums);62 63 int i = 0; 64 for (const auto& [queryIndex, x, m] : getIndexedQueries(queries)) {65 while (i < nums.size() && nums[i] <= m)66 bitTrie.insert(nums[i++]);67 if (i > 0 && nums[i - 1] <= m)68 ans[queryIndex] = bitTrie.getMaxXor(x);69 }70 71 return ans;72 }73 74 private:75 vector<IndexedQuery> getIndexedQueries(const vector<vector<int>>& queries) {76 vector<IndexedQuery> indexedQueries;77 for (int i = 0; i < queries.size(); ++i)78 indexedQueries.emplace_back(i, queries[i][0], queries[i][1]);79 ranges::sort(80 indexedQueries, ranges::less{},81 [](const IndexedQuery& indexedQuery) { return indexedQuery.m; });82 return indexedQueries;83 }84};85