leetcode
leetcode 2401 ~ 2450
统计距离为 k 的点对

统计距离为 k 的点对

难度:

标签:

题目描述

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 <= 50000
  • 0 <= xi, yi <= 106
  • 0 <= k <= 100

代码结果

运行时间: 1582 ms, 内存: 32.0 MB


/* 
 * 题目思路:
 * 使用Java Streams,我们可以利用 IntStream.range 和 flatMap 方法。
 * 外层 IntStream.range 用于遍历第一个点的索引 i,
 * flatMap 中嵌套内层 IntStream.range 用于遍历第二个点的索引 j (j > i),
 * mapToInt 用于计算异或距离,filter 用于筛选出等于 k 的距离,
 * count 方法用于统计满足条件的点对数量。
 */
import java.util.stream.IntStream;

public class Solution {
    public long countPairs(int[][] coordinates, int k) {
        return IntStream.range(0, coordinates.length)
            .flatMap(i -> IntStream.range(i + 1, coordinates.length)
                .map(j -> (coordinates[i][0] ^ coordinates[j][0]) +
                          (coordinates[i][1] ^ coordinates[j][1])))
            .filter(distance -> distance == k)
            .count();
    }
}

解释

方法:

此题解采用了哈希表来记录遍历过的坐标点,以减少查找与计算时间。对于每个点(xj, yj),通过枚举可能的(xi, yi),计算可能满足条件的(xi XOR xj) + (yi XOR yj) = k的情况。这是通过固定一个点,然后为每个可能的a值(从0到k),计算出可能的xi和yi,然后在哈希表中查找是否有这样的(xi, yi)存在。如果存在,这意味着这对点满足距离为k。通过这种方式,每个点只需要考虑k+1种可能的配对点,大大减少了必须考虑的总配对数。

时间复杂度:

O(n*k)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中,对每个点(xj, yj)的处理是否保证了所有的(xi, yi)配对都是唯一的?如果不是,是否会导致计数重复?
在题解中,对于每个点(xj, yj),算法确实可能会对某些(xi, yi)配对进行重复计数。这是因为对于不同的(xj, yj),可能会有相同的(xi, yi)满足条件。由于算法在检查(xi, yi)时没有考虑它们是否已经作为(xj, yj)被计算过,因此算法可能会对某些配对进行重复计数。为了避免这种重复计数,可以在哈希表中记录每个点作为(xi, yi)已经被考虑过的其他点(xj, yj),这样可以确保每个配对只被计数一次。
🦆
题解中提到的枚举可能的(xi, yi),是否考虑了(xi, yi)可能不在给定的coordinates数组中的情况?如果(xi, yi)不在数组中,这是否会影响最终的结果?
题解中的算法确实没有明确地检查(xi, yi)是否在给定的coordinates数组中。这意味着如果计算出的(xi, yi)不在数组中,它们不会在哈希表中找到匹配,从而不会被计算为有效的点对。因此,只有当(xi, yi)同时在数组中时,这个点对才会被计入最终的结果。这种方式确保了只有实际存在于输入数组中的点对才被计数,符合题目的要求。
🦆
算法中使用了哈希表来记录点的出现次数,这种方法是否考虑了坐标点可能重复出现的情况?如果有重复点,如何处理计数?
算法中使用的哈希表确实考虑了坐标点可能重复出现的情况。通过记录每个坐标点(xj, yj)在哈希表中的出现次数,算法能够在计算有效点对时考虑到这种重复情况。例如,如果一个点(xi, yi)在输入数组中出现多次,则每次这个点与另一个有效点(xj, yj)配对时,都会根据(xi, yi)的出现次数增加相应的计数。这样可以确保重复的点被正确地计入总数。
🦆
在题解算法中,是否有考虑到k的值非常小或非常大时,算法的表现如何?对于极端值,是否需要优化算法以防止性能问题?
在题解的算法中,如果k的值非常小,算法的性能会比较好,因为每个点(xj, yj)需要考虑的(xi, yi)数量减少。然而,如果k的值非常大,算法的性能可能会受到影响,因为每个点需要考虑的(xi, yi)可能会非常多,导致计算量增加。为了优化这种情况,可以考虑使用更高效的数据结构如空间划分树或KD树来快速查找和计算距离,或者优化哈希表的使用策略,减少不必要的计算和查找。

相关问题