Count Pairs of Points With Distance k solution and explanation
8 more videos on this problem
🔴 2857. Count Pairs of Points With Distance k II XOR II Biweekly Contest 113 II Leetcode 2857Aryan Mittal · 9:02 · 1K views
2857. Count Pairs of Points With Distance k | Leetcode Biweekly 113codingMohan · 15:51 · 695 views
2857. Count Pairs of Points With Distance kTechTalk · 7:00 · 631 views
count pairs of points with distance K #leetcodechallenge #leetcode #contestcrazy developers · 0:30 · 557 views
2857. Count Pairs of Points With Distance k || Biweekly Contest 113 || LeetcodeAshish Kumar · 17:12 · 288 views
【每日一题】LeetCode 2857. Count Pairs of Points With Distance kHuifeng Guan · 9:05 · 283 views
2857. Count Pairs of Points With Distance k (Leetcode Medium)Programming Live with Larry · 23:03 · 261 views
Leetcode Biweekly Contest 113 || Problems A, B, C || 2855, 2856, 2857 || CodeaticCode-a-tic · 17:04 · 117 views
2857. Count Pairs of Points With Distance k || LeetcodeDCC NITA · 6:09 · 109 views
The problem
You are given a 2D integer array coordinates and an integer k, where coordinates[i] = [xi, yi] are the coordinates of the ith point in a 2D plane.
We define the distance between two points (x1, y1) and (x2, y2) as (x1 XOR x2) + (y1 XOR y2) where XOR is the bitwise XOR operation.
Return the number of pairs (i, j) such that i < j and the distance between points i and j is equal to k.
Example 1:
Input: coordinates = [[1,2],[4,2],[1,3],[5,2]], k = 5 Output: 2 Explanation: We can choose the following pairs: - (0,1): Because we have (1 XOR 4) + (2 XOR 2) = 5. - (2,3): Because we have (1 XOR 5) + (3 XOR 2) = 5.
Example 2:
Input: coordinates = [[1,3],[1,3],[1,3],[1,3],[1,3]], k = 0 Output: 10 Explanation: Any two chosen pairs will have a distance of 0. There are 10 ways to choose two pairs.
Constraints:
2 <= coordinates.length <= 500000 <= xi, yi <= 1060 <= k <= 100
Approach overview
Problem Overview: You receive a list of 2D points [x, y] and an integer k. A pair of points is valid when (x1 XOR x2) + (y1 XOR y2) = k. The task is to count how many unique pairs satisfy this condition without double counting.
The expression mixes coordinate math with XOR operations, which makes typical distance formulas or geometric tricks unusable. The key observation: if (x1 XOR x2) + (y1 XOR y2) = k, then for any possible value dx = x1 XOR x2, the corresponding dy must be k - dx. That reduces the search space dramatically.
Approach 1: Hash Map Enumeration (O(n * k) time, O(n) space)
Use a frequency hash table that stores previously seen points. Iterate through each point (x, y). For every possible value dx from 0 to k, compute dy = k - dx. If x1 XOR x2 = dx, then the matching x-coordinate must be x2 = x ^ dx. Similarly, y2 = y ^ dy. Check the hash map to see if this target point already exists and add its frequency to the answer. After processing all dx splits, insert the current point into the map.
This works because XOR is reversible: if a XOR b = c, then b = a XOR c. Instead of scanning all previous points, you directly compute the only coordinates that could satisfy the equation. The loop over 0..k bounds the search. This approach combines bit manipulation with constant‑time hash lookups.
Approach 2: Sorting and Two-Pointer Technique (O(n log n + n * k) time, O(1) extra space)
Another strategy sorts the points (typically by x, then y). Sorting helps process candidate pairs in a predictable order and avoids repeated map allocations. For each point, iterate through possible dx values and compute the target x-coordinate x ^ dx. Since the array is sorted, you can restrict the search to the subrange where this x-coordinate appears. Within that range, use a two-pointer style scan or binary search to check candidate y values that satisfy y1 XOR y2 = k - dx.
The idea is to reduce unnecessary comparisons by leveraging ordering instead of hashing. In practice, this approach is slightly more complex but avoids additional memory. It still relies on the same XOR decomposition of the distance formula.
Recommended for interviews: The hash map approach is the expected solution. It shows you recognize the XOR reversibility trick and use a constant-time lookup structure. Mentioning the brute force O(n^2) pair scan demonstrates baseline reasoning, but implementing the hash-based method shows strong command of array iteration, hashing, and bitwise manipulation.
Approach 1: Approach 1: Using a Hash Map
This approach utilizes a hash map to store elements and their indices for quick lookup. The main idea is to iterate through the given data structure (e.g., list or array) and check if the desired complement exists in the hash map. This method improves efficiency by reducing the need for nested iterations.
def find_pair(nums, target):
hash_map = {}
for i, num in enumerate(nums):
complement = target - num
if complement in hash_map:
print(f"Pair found at indices: {hash_map[complement]} and {i}")
return
hash_map[num] = i
print("No valid pair found.")
nums = [2, 7, 11, 15]
target = 9
find_pair(nums, target)import java.util.HashMap;
public class PairFinder {
public static void findPair(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
System.out.println("Pair found at indices: " + map.get(complement) + " and " + i);
return;
}
map.put(nums[i], i);
}
System.out.println("No valid pair found.");
}
public static void main(String[] args) {
int[] nums = {2, 7, 11, 15};
int target = 9;
findPair(nums, target);
}
}#include <iostream>
#include <unordered_map>
#include <vector>
void findPair(std::vector<int>& nums, int target) {
std::unordered_map<int, int> hashMap;
for (int i = 0; i < nums.size(); i++) {
int complement = target - nums[i];
if (hashMap.find(complement) != hashMap.end()) {
std::cout << "Pair found at indices: " << hashMap[complement] << " and " << i << std::endl;
return;
}
hashMap[nums[i]] = i;
}
std::cout << "No valid pair found." << std::endl;
}
int main() {
std::vector<int> nums = {2, 7, 11, 15};
int target = 9;
findPair(nums, target);
return 0;
}function findPair(nums, target) {
const hashMap = new Map();
for (let i = 0; i < nums.length; i++) {
const complement = target - nums[i];
if (hashMap.has(complement)) {
console.log(`Pair found at indices: ${hashMap.get(complement)} and ${i}`);
return;
}
hashMap.set(nums[i], i);
}
console.log("No valid pair found.");
}
const nums = [2, 7, 11, 15];
const target = 9;
findPair(nums, target);#include <stdio.h>
#include <stdlib.h>
typedef struct {
int key;
int value;
} MapEntry;
void findPair(int* nums, int numsSize, int target) {
MapEntry* hashTable = (MapEntry*)malloc(numsSize * sizeof(MapEntry));
int i, j, found = 0;
for (i = 0; i < numsSize; i++) {
int complement = target - nums[i];
for (j = 0; j < i; j++) {
if (hashTable[j].key == complement) {
printf("Pair found at indices: %d and %d\n", hashTable[j].value, i);
found = 1;
break;
}
}
if (found) break;
hashTable[i].key = nums[i];
hashTable[i].value = i;
}
if (!found) printf("No valid pair found.\n");
free(hashTable);
}
int main() {
int nums[] = {2, 7, 11, 15};
int target = 9;
findPair(nums, 4, target);
return 0;
}using System;
using System.Collections.Generic;
class Program {
static void FindPair(int[] nums, int target) {
Dictionary<int, int> hashMap = new Dictionary<int, int>();
for (int i = 0; i < nums.Length; i++) {
int complement = target - nums[i];
if (hashMap.ContainsKey(complement)) {
Console.WriteLine($"Pair found at indices: {hashMap[complement]} and {i}");
return;
}
hashMap[nums[i]] = i;
}
Console.WriteLine("No valid pair found.");
}
static void Main() {
int[] nums = {2, 7, 11, 15};
int target = 9;
FindPair(nums, target);
}
}The Python solution employs a dictionary as a hash map. By iterating over the list with enumeration, we keep track of indices while checking and storing numbers and their respective indices for quick complement look-up.
Time Complexity: O(n), since each element is processed with constant time operations.
Space Complexity: O(n), equivalent to storing the elements in the hash map.
Approach 2: Approach 2: Sorting and Two-Pointer Technique
This approach involves sorting the input, then using a two-pointer technique to find pairs. The idea is to sort the array and use two indices starting from both ends of the array, moving inwards based on comparison with the target sum. This approach avoids using extra space for hash tables.
def find_pair(nums, target):
nums.sort()
start, end = 0, len(nums) - 1
while start < end:
current_sum = nums[start] + nums[end]
if current_sum == target:
print(f"Pair found: {nums[start]} and {nums[end]}")
return
elif current_sum < target:
start += 1
else:
end -= 1
print("No valid pair found.")
nums = [2, 7, 11, 15]
target = 9
find_pair(nums, target)import java.util.Arrays;
public class PairFinder {
public static void findPair(int[] nums, int target) {
Arrays.sort(nums);
int start = 0, end = nums.length - 1;
while (start < end) {
int sum = nums[start] + nums[end];
if (sum == target) {
System.out.println("Pair found: " + nums[start] + " and " + nums[end]);
return;
} else if (sum < target) {
start++;
} else {
end--;
}
}
System.out.println("No valid pair found.");
}
public static void main(String[] args) {
int[] nums = {2, 7, 11, 15};
int target = 9;
findPair(nums, target);
}
}#include <iostream>
#include <vector>
#include <algorithm>
void findPair(std::vector<int> nums, int target) {
std::sort(nums.begin(), nums.end());
int start = 0, end = nums.size() - 1;
while (start < end) {
int sum = nums[start] + nums[end];
if (sum == target) {
std::cout << "Pair found: " << nums[start] << " and " << nums[end] << std::endl;
return;
} else if (sum < target) {
start++;
} else {
end--;
}
}
std::cout << "No valid pair found." << std::endl;
}
int main() {
std::vector<int> nums = {2, 7, 11, 15};
int target = 9;
findPair(nums, target);
return 0;
}function findPair(nums, target) {
nums.sort((a, b) => a - b);
let start = 0, end = nums.length - 1;
while (start < end) {
let sum = nums[start] + nums[end];
if (sum === target) {
console.log(`Pair found: ${nums[start]} and ${nums[end]}`);
return;
} else if (sum < target) {
start++;
} else {
end--;
}
}
console.log("No valid pair found.");
}
const nums = [2, 7, 11, 15];
const target = 9;
findPair(nums, target);#include <stdio.h>
#include <stdlib.h>
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
void findPair(int* nums, int numsSize, int target) {
qsort(nums, numsSize, sizeof(int), compare);
int start = 0, end = numsSize - 1;
while (start < end) {
int sum = nums[start] + nums[end];
if (sum == target) {
printf("Pair found: %d and %d\n", nums[start], nums[end]);
return;
} else if (sum < target) {
start++;
} else {
end--;
}
}
printf("No valid pair found.\n");
}
int main() {
int nums[] = {2, 7, 11, 15};
int target = 9;
findPair(nums, 4, target);
return 0;
}using System;
class Program {
static void FindPair(int[] nums, int target) {
Array.Sort(nums);
int start = 0, end = nums.Length - 1;
while (start < end) {
int sum = nums[start] + nums[end];
if (sum == target) {
Console.WriteLine($"Pair found: {nums[start]} and {nums[end]}");
return;
} else if (sum < target) {
start++;
} else {
end--;
}
}
Console.WriteLine("No valid pair found.");
}
static void Main() {
int[] nums = {2, 7, 11, 15};
int target = 9;
FindPair(nums, target);
}
}Python's sort method is applied to the array first. Using two pointers, we iterate from both start and end, comparing the sum at these indices with the target for the required pair.
Time Complexity: O(n log n), due to the sorting operation.
Space Complexity: O(1), assuming in-place array manipulation.
Approach 3: Hash Table + Enumeration
We can use a hash table cnt to count the occurrence of each point in the array coordinates.
Next, we enumerate each point (x_2, y_2) in the array coordinates. Since the range of k is [0, 100], and the result of x_1 \oplus x_2 or y_1 \oplus y_2 is always greater than or equal to 0, we can enumerate the result a of x_1 \oplus x_2 in the range [0,..k]. Then, the result of y_1 \oplus y_2 is b = k - a. In this way, we can calculate the values of x_1 and y_1, and add the occurrence of (x_1, y_1) to the answer.
The time complexity is O(n times k), and the space complexity is O(n). Here, n is the length of the array coordinates.
function countPairs(coordinates: number[][], k: number): number {
const cnt: Map<number, number> = new Map();
const f = (x: number, y: number): number => x * 1000000 + y;
let ans = 0;
for (const [x2, y2] of coordinates) {
for (let a = 0; a <= k; ++a) {
const b = k - a;
const [x1, y1] = [a ^ x2, b ^ y2];
ans += cnt.get(f(x1, y1)) ?? 0;
}
cnt.set(f(x2, y2), (cnt.get(f(x2, y2)) ?? 0) + 1);
}
return ans;
}func countPairs(coordinates [][]int, k int) (ans int) {
cnt := map[[2]int]int{}
for _, c := range coordinates {
x2, y2 := c[0], c[1]
for a := 0; a <= k; a++ {
b := k - a
x1, y1 := a^x2, b^y2
ans += cnt[[2]int{x1, y1}]
}
cnt[[2]int{x2, y2}]++
}
return
}Complexity comparison
| Approach | Complexity |
|---|---|
| Approach 1: Using a Hash Map | Time Complexity: O(n), since each element is processed with constant time operations. |
| Approach 2: Sorting and Two-Pointer Technique | Time Complexity: O(n log n), due to the sorting operation. |
| Hash Table + Enumeration | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Pair Check | O(n²) | O(1) | Small input sizes or when first reasoning about the problem |
| Hash Map Enumeration | O(n * k) | O(n) | General case; fastest and simplest interview solution |
| Sorting + Two-Pointer Search | O(n log n + n * k) | O(1) | When minimizing extra memory or working with pre-sorted data |
Frequently asked questions
Is Count Pairs of Points With Distance k easy or hard?
The problem is rated Medium because the core difficulty is recognizing the XOR transformation. Once you realize that x2 = x1 ^ dx and y2 = y1 ^ dy, the solution becomes a straightforward hash map lookup combined with enumeration of k splits.
Count Pairs of Points With Distance k Python/Java solution
Python solutions typically use a dictionary with tuple keys like (x, y). Java implementations use a HashMap with encoded coordinates or a pair class. Both follow the same logic: iterate dx from 0..k, compute (x ^ dx, y ^ (k - dx)), and accumulate counts from the map.
How to solve Count Pairs of Points With Distance k in O(n)?
Strict O(n) is not achievable because the algorithm must consider every possible split of k into dx and dy. The closest practical complexity is O(n * k). For each point, compute candidate coordinates using XOR reversibility and check them in a hash map.
What is the best approach for Count Pairs of Points With Distance k?
The most practical approach uses a hash map with XOR enumeration. For each point (x, y), iterate dx from 0 to k and compute dy = k - dx. The only coordinates that could satisfy the equation are (x ^ dx, y ^ dy). A hash map lookup checks if that point already appeared. This runs in O(n * k) time with O(n) space.
Is Count Pairs of Points With Distance k asked at Google/Amazon/Meta?
Problems combining hashing and bit manipulation frequently appear in interviews at companies like Amazon, Google, and Meta. Variants involving XOR properties, coordinate hashing, or pair counting are common because they test both algorithmic insight and data structure choice.
What data structure is used in Count Pairs of Points With Distance k?
A hash table (hash map) is the primary data structure. It stores counts of previously seen coordinate pairs so valid matches can be found in constant time while iterating through the points.
What is the time complexity of Count Pairs of Points With Distance k?
The optimized hash map solution runs in O(n * k) time because each point checks k+1 possible XOR splits. Hash lookups are O(1) on average. Space complexity is O(n) for storing previously seen points.
