- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 135 lines of C++ from the credited upstream file maximum-subarray-xor-with-bounded-range.cpp.
- The implementation visibly relies on sequence storage, hash lookup, work queue.
- 13 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 45class Solution {6public:7 int maxXor(vector<int>& nums, int k) {8 vector<int> lookup(size(nums), -1);9 deque<int> max_dq, min_dq;10 for (int right = 0, left = 0; right < size(nums); ++right) {11 while (!empty(max_dq) && nums[max_dq.back()] <= nums[right]) {12 max_dq.pop_back();13 }14 max_dq.emplace_back(right);15 while (!empty(min_dq) && nums[min_dq.back()] >= nums[right]) {16 min_dq.pop_back();17 }18 min_dq.emplace_back(right);19 while (nums[max_dq[0]] - nums[min_dq[0]] > k) {20 if (!empty(max_dq) && max_dq[0] == left) {21 max_dq.pop_front();22 }23 if (!empty(min_dq) && min_dq[0] == left) {24 min_dq.pop_front();25 }26 ++left;27 }28 lookup[right] = left;29 }30 int result = 0;31 const uint32_t mx = max(ranges::max(nums), 1);32 for (int i = bit_width(mx) - 1; i >= 0; --i) {33 unordered_map<int, int> lookup2;34 lookup2[0] = 0;35 for (int right = 0, prefix = 0; right < size(nums); ++right) {36 prefix ^= nums[right] >> i;37 if (lookup2.count(((result >> i) | 1) ^ prefix) && lookup2[((result >> i) | 1) ^ prefix] >= lookup[right]) {38 result |= 1 << i;39 break;40 }41 lookup2[prefix] = right + 1;42 }43 }44 return result;45 }46};47 48495051class Solution2 {52private:53 class Trie {54 public:55 Trie(int bit_length)56 : bit_length_(bit_length)57 , nodes_() {58 new_node();59 }60 61 void add(int num, int diff) {62 int curr = 0;63 for (int i = bit_length_ - 1; i >= 0; --i) {64 const auto& x = (num >> i) & 1;65 if (nodes_[curr][x] == -1) {66 nodes_[curr][x] = new_node();67 }68 curr = nodes_[curr][x];69 cnts_[curr] += diff;70 }71 }72 73 int query(int prefix) {74 int result = 0, curr = 0;75 for (int i = bit_length_ - 1; i >= 0 && curr != -1; --i) {76 const auto& x = (prefix >> i) & 1;77 if (nodes_[curr][x ^ 1] != -1 && cnts_[nodes_[curr][x ^ 1]]) {78 result |= 1 << i;79 curr = nodes_[curr][x ^ 1];80 } else {81 curr = nodes_[curr][x];82 }83 }84 return result;85 }86 87 private:88 int new_node() {89 nodes_.push_back(array<int, 2>{-1, -1});90 cnts_.emplace_back(0);91 return size(nodes_) - 1;92 }93 94 const int bit_length_;95 vector<array<int, 2>> nodes_;96 vector<int> cnts_;97 };98 99public:100 int maxXor(vector<int>& nums, int k) {101 int result = 0;102 vector<int> prefix(size(nums) + 1);103 for (int i = 0; i < size(nums); ++i) {104 prefix[i + 1] = prefix[i] ^ nums[i];105 }106 const uint32_t mx = max(ranges::max(nums), 1);107 Trie trie(bit_width(mx));108 trie.add(prefix[0], +1);109 deque<int> max_dq, min_dq;110 for (int right = 0, left = 0; right < size(nums); ++right) {111 while (!empty(max_dq) && nums[max_dq.back()] <= nums[right]) {112 max_dq.pop_back();113 }114 max_dq.emplace_back(right);115 while (!empty(min_dq) && nums[min_dq.back()] >= nums[right]) {116 min_dq.pop_back();117 }118 min_dq.emplace_back(right);119 while (nums[max_dq[0]] - nums[min_dq[0]] > k) {120 trie.add(prefix[left], -1);121 if (!empty(max_dq) && max_dq[0] == left) {122 max_dq.pop_front();123 }124 if (!empty(min_dq) && min_dq[0] == left) {125 min_dq.pop_front();126 }127 ++left;128 }129 result = max(result, trie.query(prefix[right + 1]));130 trie.add(prefix[right + 1], +1);131 }132 return result;133 }134};135