leetcode
leetcode 2751 ~ 2800
按距离统计房屋对数目 II

按距离统计房屋对数目 II

难度:

标签:

题目描述

You are given three positive integers n, x, and y.

In a city, there exist houses numbered 1 to n connected by n streets. There is a street connecting the house numbered i with the house numbered i + 1 for all 1 <= i <= n - 1 . An additional street connects the house numbered x with the house numbered y.

For each k, such that 1 <= k <= n, you need to find the number of pairs of houses (house1, house2) such that the minimum number of streets that need to be traveled to reach house2 from house1 is k.

Return a 1-indexed array result of length n where result[k] represents the total number of pairs of houses such that the minimum streets required to reach one house from the other is k.

Note that x and y can be equal.

 

Example 1:

Input: n = 3, x = 1, y = 3
Output: [6,0,0]
Explanation: Let's look at each pair of houses:
- For the pair (1, 2), we can go from house 1 to house 2 directly.
- For the pair (2, 1), we can go from house 2 to house 1 directly.
- For the pair (1, 3), we can go from house 1 to house 3 directly.
- For the pair (3, 1), we can go from house 3 to house 1 directly.
- For the pair (2, 3), we can go from house 2 to house 3 directly.
- For the pair (3, 2), we can go from house 3 to house 2 directly.

Example 2:

Input: n = 5, x = 2, y = 4
Output: [10,8,2,0,0]
Explanation: For each distance k the pairs are:
- For k == 1, the pairs are (1, 2), (2, 1), (2, 3), (3, 2), (2, 4), (4, 2), (3, 4), (4, 3), (4, 5), and (5, 4).
- For k == 2, the pairs are (1, 3), (3, 1), (1, 4), (4, 1), (2, 5), (5, 2), (3, 5), and (5, 3).
- For k == 3, the pairs are (1, 5), and (5, 1).
- For k == 4 and k == 5, there are no pairs.

Example 3:

Input: n = 4, x = 1, y = 1
Output: [6,4,2,0]
Explanation: For each distance k the pairs are:
- For k == 1, the pairs are (1, 2), (2, 1), (2, 3), (3, 2), (3, 4), and (4, 3).
- For k == 2, the pairs are (1, 3), (3, 1), (2, 4), and (4, 2).
- For k == 3, the pairs are (1, 4), and (4, 1).
- For k == 4, there are no pairs.

 

Constraints:

  • 2 <= n <= 105
  • 1 <= x, y <= n

代码结果

运行时间: 484 ms, 内存: 25.2 MB


/*
 * Solution Idea using Java Streams:
 * 1. Stream through pairs of houses, calculate the shortest distance for each pair.
 * 2. Collect the results using toMap and convert it to an array.
 */

import java.util.stream.IntStream;
import java.util.stream.Collectors;
import java.util.Map;

public int[] countPairsStream(int n, int x, int y) {
    Map<Integer, Long> countMap = IntStream.rangeClosed(1, n - 1)
        .boxed()
        .flatMap(i -> IntStream.rangeClosed(i + 1, n)
            .mapToObj(j -> Math.min(j - i, Math.abs(x - i) + 1 + Math.abs(y - j))))
        .collect(Collectors.groupingBy(k -> k, Collectors.counting()));

    return IntStream.rangeClosed(1, n)
        .map(i -> countMap.getOrDefault(i, 0L).intValue())
        .toArray();
}

解释

方法:

题解采用差分数组的方法来计算每个可能距离 k 下的房屋对数量。通过差分数组,能够高效地统计区间内的变化量,从而避免重复计算。整体策略涉及将房屋排列成一个环状和线性的结构,考虑额外连接的 x 和 y 形成的特殊路径。计算过程首先确定 x 和 y 的位置关系,使得 x 总是小于等于 y。接着计算 x 和 y 形成的环状结构的长度,并对不同的距离 k 计算可能的房屋对数量。这涉及到环内的计算以及环与直链之间的计算。差分数组被用于记录和更新距离变化,最终通过累加差分数组来得到每个距离下的房屋对数。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在初始化差分数组时,使用的初始值是 `(linkLength - 1) << 1` 和 `-queue[0] - 2`?这样的初始化逻辑是基于什么考虑?
在初始化差分数组时,初始值 `(linkLength - 1) << 1` 代表的是链条的长度(不包括两端的 x 和 y),每个间隔可以形成的房屋对数乘以 2(因为每对房屋可以互换位置)。这样设置是为了在累加差分数组时,每次遍历到的位置都能反映出从起点开始直到当前位置的累加房屋对数。使用 `-queue[0] - 2` 是为了在差分数组的第二个位置产生一个负的大幅调整,以结束初始设置的影响,保证后续计算的正确性。
🦆
在计算环的长度和环的半长时,为什么需要检查环的长度是否大于2,并对应地调整结果数组 `ans[0]` 的值?
环的长度大于2时,意味着环内至少有三个房屋,可以形成有效的房屋对。在这种情况下,环内的房屋对对差分数组的影响需要特别处理,尤其是考虑到环的对称性和可能的重叠。调整 `ans[0]` 的值是为了消除在环形结构中房屋自身与自身配对的可能性,因为在环的逻辑中,每个房屋都与环中的其他房屋形成对,而不包括自己。
🦆
函数 `add(head: int, length: int, num: int)` 中,差分数组的更新逻辑是如何影响最终结果数组 `ans` 的?能否详细解释一下差分数组的工作机制?
差分数组是一种用来高效处理区间更新和查询的数据结构。`add` 函数通过在差分数组的 `head` 位置增加 `num`,然后在 `head + length` 位置减去 `num`,来表示从 `head` 开始,长度为 `length` 的区间内每个元素都增加 `num`。在通过差分数组更新后,累加差分数组就可以得到每个位置的实际值。在本题中,这种操作用于动态调整每个距离下的房屋对数量,最终通过累加差分数组的结果来填充结果数组 `ans`,每个索引位置的 `ans` 值表示对应距离下的房屋对数量。

相关问题