Given a (0-indexed) integer array nums and two integers low and high, return the number of nice pairs.
A nice pair is a pair (i, j) where 0 <= i < j < nums.length and low <= (nums[i] XOR nums[j]) <= high.
Example 1:
Input: nums = [1,4,2,7], low = 2, high = 6
Output: 6
Explanation: All nice pairs (i, j) are as follows:
- (0, 1): nums[0] XOR nums[1] = 5
- (0, 2): nums[0] XOR nums[2] = 3
- (0, 3): nums[0] XOR nums[3] = 6
- (1, 2): nums[1] XOR nums[2] = 6
- (1, 3): nums[1] XOR nums[3] = 3
- (2, 3): nums[2] XOR nums[3] = 5
Example 2:
Input: nums = [9,8,4,2,1], low = 5, high = 14 Output: 8 Explanation: All nice pairs (i, j) are as follows: - (0, 2): nums[0] XOR nums[2] = 13 - (0, 3): nums[0] XOR nums[3] = 11 - (0, 4): nums[0] XOR nums[4] = 8 - (1, 2): nums[1] XOR nums[2] = 12 - (1, 3): nums[1] XOR nums[3] = 10 - (1, 4): nums[1] XOR nums[4] = 9 - (2, 3): nums[2] XOR nums[3] = 6 - (2, 4): nums[2] XOR nums[4] = 5
Constraints:
1 <= nums.length <= 2 * 1041 <= nums[i] <= 2 * 1041 <= low <= high <= 2 * 104When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force way to solve this is to check every single possible pair of numbers we're given. For each pair, we'll calculate their XOR value and see if it falls within our specified range.
Here's how the algorithm would work step-by-step:
def count_xor_pairs_brute_force(
numbers, lower_bound, upper_bound
):
pair_count = 0
# Iterate through each number in the list.
for first_number_index in range(len(numbers)):
for second_number_index in range(
first_number_index + 1, len(numbers)
):
# Calculating the XOR value is key to the problem.
xor_result = (
numbers[first_number_index]
^ numbers[second_number_index]
)
# Check if the XOR value falls within the specified range
if (
xor_result >= lower_bound
and xor_result <= upper_bound
):
# Increment the count if the XOR value is in range
pair_count += 1
return pair_countThe efficient strategy avoids checking every single pair of numbers. It smartly organizes and analyzes the numbers bit by bit to count the pairs that fit within the desired range.
Here's how the algorithm would work step-by-step:
class TrieNode:
def __init__(self):
self.children = [None] * 2
self.count = 0
class Solution:
def countPairs(self, numbers: list[int], low_range: int, high_range: int) -> int:
def get_count_less_than_or_equal_to(maximum_value: int) -> int:
trie_root = TrieNode()
count = 0
def insert_number(number: int):
current_node = trie_root
for bit_index in range(15, -1, -1):
bit = (number >> bit_index) & 1
if not current_node.children[bit]:
current_node.children[bit] = TrieNode()
current_node = current_node.children[bit]
current_node.count += 1
def find_pairs(number: int, max_xor: int) -> int:
current_node = trie_root
pair_count = 0
for bit_index in range(15, -1, -1):
number_bit = (number >> bit_index) & 1
max_xor_bit = (max_xor >> bit_index) & 1
if max_xor_bit == 1:
#If current bit of max_xor is 1, explore the opposite bit.
if current_node.children[1 - number_bit]:
pair_count += current_node.children[1 - number_bit].count
# Move to the next bit in the same direction.
if not current_node.children[number_bit]:
return pair_count
current_node = current_node.children[number_bit]
else:
# If current bit of max_xor is 0, explore the same bit.
if not current_node.children[1 - number_bit]:
return pair_count
current_node = current_node.children[1 - number_bit]
pair_count += current_node.count
return pair_count
for number in numbers:
insert_number(number)
for number in numbers:
count += find_pairs(number, maximum_value)
return count // 2
# Calculating pairs within the high range.
high_count = get_count_less_than_or_equal_to(high_range)
# Calculating pairs less than the low range.
low_count = get_count_less_than_or_equal_to(low_range - 1)
# Subtract to find pairs within the specified range.
return high_count - low_count| Case | How to Handle |
|---|---|
| Null input array | Throw an IllegalArgumentException or return 0 to indicate invalid input |
| Array with fewer than 2 elements | Return 0 because a pair cannot be formed |
| Lower bound greater than upper bound | Return 0 because the range is invalid |
| Large array with a wide range of values leading to potential integer overflow in XOR operation | Use a data type with sufficient capacity (e.g., long) to store the XOR result, or check before operations to prevent overflow |
| Array contains negative numbers | Ensure the XOR operation and range comparison handle negative values correctly; negative XOR results are valid |
| Lower bound and upper bound are both zero | Count pairs with XOR equal to 0, which typically means counting pairs of identical numbers |
| All elements in the array are identical | Efficiently calculate the number of pairs using combinatorics n*(n-1)/2 where n is number of elements |
| Extreme boundary values for array elements or target range (close to max int) | Be cautious of potential integer overflow during XOR or range comparison operations; consider using larger data types |