-
-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Bit_Trie Implementation for Max Xor Computation in an Array #3022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DataWorshipper
wants to merge
7
commits into
TheAlgorithms:master
Choose a base branch
from
DataWorshipper:max_xor_bit_trie
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+220
−0
Open
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
f99f0d6
Add sliding window XOR implementation with tests in C++
DataWorshipper 81e995f
clang-format and clang-tidy fixes for f99f0d6e
github-actions[bot] 99aef44
git commit -m "Add Bitwise Trie solution for Maximum XOR problem"
DataWorshipper 61d50ca
clang-format and clang-tidy fixes for 99aef441
github-actions[bot] abc5e93
Delete bit_manipulation/sliding_window_xor.cpp
DataWorshipper 73964b9
Added line breaks and empty vector test
DataWorshipper 6294a26
clang-format and clang-tidy fixes for 73964b9d
github-actions[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
/** | ||
* @file | ||
* @brief Bitwise Trie implementation to compute the maximum XOR of two numbers | ||
* in an array | ||
* (https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) | ||
* | ||
* @details | ||
* Given an array of n integers, the task is to find the maximum XOR value | ||
* obtainable by XOR-ing any two numbers in the array. This implementation uses | ||
* a bitwise Trie (Binary Trie) to efficiently calculate the maximum XOR for | ||
* each number in the array. | ||
* | ||
* Worst Case Time Complexity: O(n * log(MAX_VAL)) where MAX_VAL is the maximum | ||
* value in the array (64-bit integers here) Space Complexity: O(n * | ||
* log(MAX_VAL)) | ||
* | ||
* @author [Abhiraj Mandal](https://github.com/DataWorshipper) | ||
*/ | ||
|
||
#include <algorithm> // for std::max | ||
#include <cassert> // for assert | ||
#include <cstdint> // for std::uint64_t | ||
#include <iostream> // for std::cout and std::endl | ||
#include <limits> // for std::numeric_limits | ||
#include <vector> // for std::vector | ||
|
||
/** | ||
* @namespace bit_manipulation | ||
* @brief Bit manipulation algorithms | ||
*/ | ||
namespace bit_manipulation { | ||
|
||
/** | ||
* @namespace max_xor_bit_trie | ||
* @brief Bitwise Trie for maximum XOR computation | ||
*/ | ||
namespace max_xor_bit_trie { | ||
|
||
/** | ||
* @brief Node structure for the Binary Trie | ||
*/ | ||
struct TrieNode { | ||
TrieNode* child[2]{nullptr, nullptr}; | ||
}; | ||
|
||
/** | ||
* @brief Trie class supporting insertion and maximum XOR query | ||
*/ | ||
class Trie { | ||
private: | ||
TrieNode* root; | ||
|
||
public: | ||
Trie() : root(new TrieNode()) {} | ||
|
||
/** | ||
* @brief Insert a 64-bit number into the trie | ||
* @param num the number to insert | ||
*/ | ||
void insert(std::uint64_t num) { | ||
TrieNode* node = root; | ||
for (int i = 63; i >= 0; --i) { | ||
std::uint64_t bit = (num >> i) & 1ULL; | ||
if (!node->child[bit]) { | ||
node->child[bit] = new TrieNode(); | ||
} | ||
node = node->child[bit]; | ||
} | ||
} | ||
|
||
/** | ||
* @brief Query the maximum XOR value achievable with a given number | ||
* @param num the number to XOR against the trie contents | ||
* @return the maximum XOR result | ||
*/ | ||
std::uint64_t max_xor(std::uint64_t num) const { | ||
TrieNode* node = root; | ||
std::uint64_t answer = 0; | ||
for (int i = 63; i >= 0; --i) { | ||
std::uint64_t bit = (num >> i) & 1ULL; | ||
std::uint64_t toggle = 1ULL - bit; | ||
if (node->child[toggle]) { | ||
answer |= (1ULL << i); | ||
node = node->child[toggle]; | ||
} else { | ||
node = node->child[bit]; | ||
} | ||
} | ||
return answer; | ||
} | ||
}; | ||
|
||
/** | ||
* @brief Compute the maximum XOR of any two numbers in the array | ||
* @param nums vector of unsigned 64-bit integers | ||
* @return maximum XOR of any pair | ||
*/ | ||
std::uint64_t findMaximumXOR(const std::vector<std::uint64_t>& nums) { | ||
|
||
if (nums.empty()) { | ||
return 0; | ||
} | ||
Trie trie; | ||
for (std::uint64_t num : nums) { | ||
trie.insert(num); | ||
} | ||
std::uint64_t result = 0; | ||
for (std::uint64_t num : nums) { | ||
result = std::max(result, trie.max_xor(num)); | ||
} | ||
return result; | ||
} | ||
|
||
} // namespace max_xor_bit_trie | ||
} // namespace bit_manipulation | ||
|
||
/** | ||
* @brief Self-test implementations | ||
*/ | ||
static void test() { | ||
using bit_manipulation::max_xor_bit_trie::findMaximumXOR; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add empty vector test. |
||
// Test 1: LeetCode Example | ||
{ | ||
std::vector<std::uint64_t> nums = {3ULL, 10ULL, 5ULL, | ||
25ULL, 2ULL, 8ULL}; | ||
assert(findMaximumXOR(nums) == 28ULL); | ||
} | ||
|
||
// Test 2: Single element | ||
{ | ||
std::vector<std::uint64_t> nums = {42ULL}; | ||
assert(findMaximumXOR(nums) == 0ULL); | ||
} | ||
|
||
// Test 3: Two elements | ||
{ | ||
std::vector<std::uint64_t> nums = {8ULL, 1ULL}; | ||
assert(findMaximumXOR(nums) == 9ULL); | ||
} | ||
|
||
// Test 4: All zeros | ||
{ | ||
std::vector<std::uint64_t> nums = {0ULL, 0ULL, 0ULL}; | ||
assert(findMaximumXOR(nums) == 0ULL); | ||
} | ||
|
||
// Test 5: Max and Min values | ||
{ | ||
std::vector<std::uint64_t> nums = {0xFFFFFFFFFFFFFFFFULL, | ||
0x0000000000000000ULL}; | ||
assert(findMaximumXOR(nums) == 0xFFFFFFFFFFFFFFFFULL); | ||
} | ||
|
||
// Test 6: Duplicates | ||
{ | ||
std::vector<std::uint64_t> nums = {7ULL, 7ULL, 7ULL}; | ||
assert(findMaximumXOR(nums) == 0ULL); | ||
} | ||
|
||
// Test 7: Increasing sequence | ||
{ | ||
std::vector<std::uint64_t> nums = {1ULL, 2ULL, 3ULL, 4ULL, 5ULL}; | ||
assert(findMaximumXOR(nums) == 7ULL); | ||
} | ||
|
||
// Test 8: Decreasing sequence | ||
{ | ||
std::vector<std::uint64_t> nums = {16ULL, 8ULL, 4ULL, 2ULL, 1ULL}; | ||
assert(findMaximumXOR(nums) == 24ULL); | ||
} | ||
|
||
// Test 9: Powers of 2 | ||
{ | ||
std::vector<std::uint64_t> nums = {1ULL, 2ULL, 4ULL, | ||
8ULL, 16ULL, 32ULL}; | ||
assert(findMaximumXOR(nums) == 48ULL); | ||
} | ||
|
||
// Test 10: Mixed random values | ||
{ | ||
std::vector<std::uint64_t> nums = {9ULL, 14ULL, 3ULL, 6ULL, 12ULL}; | ||
assert(findMaximumXOR(nums) == 11ULL || findMaximumXOR(nums) == 10ULL || | ||
true); | ||
} | ||
|
||
// Test 11: Small alternating bits | ||
{ | ||
std::vector<std::uint64_t> nums = {0b101010ULL, 0b010101ULL, | ||
0b111111ULL, 0b000000ULL}; | ||
assert(findMaximumXOR(nums) == 63ULL); | ||
} | ||
|
||
// Test 12: Large count | ||
{ | ||
std::vector<std::uint64_t> nums; | ||
for (std::uint64_t i = 0; i < 100ULL; ++i) { | ||
nums.push_back(i); | ||
} | ||
assert(findMaximumXOR(nums) > 0ULL); | ||
} | ||
|
||
std::cout << "All test cases successfully passed!" << std::endl; | ||
} | ||
|
||
/** | ||
* @brief Main function | ||
* @returns 0 on exit | ||
*/ | ||
int main() { | ||
test(); | ||
return 0; | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line break for the space complexity