统计数组中好三元组数目
难度:
标签:
题目描述
代码结果
运行时间: 448 ms, 内存: 32.6 MB
// Java Stream solution for counting good triplets
// Problem: Given two arrays nums1 and nums2, find the number of good triplets (x, y, z)
// where the order of elements in both arrays is the same.
// Approach:
// 1. Use a stream to map the elements of nums1 and nums2 to their indices.
// 2. Filter the triplets in nums1 and check if the indices in nums2 follow the same order.
// 3. Count such triplets.
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
public class GoodTripletsStream {
public long countGoodTriplets(int[] nums1, int[] nums2) {
int n = nums1.length;
Map<Integer, Integer> posInNums1 = new HashMap<>();
Map<Integer, Integer> posInNums2 = new HashMap<>();
// Store the positions of elements in nums1 and nums2
IntStream.range(0, n).forEach(i -> {
posInNums1.put(nums1[i], i);
posInNums2.put(nums2[i], i);
});
// Count good triplets
return IntStream.range(0, n)
.boxed()
.flatMap(i -> IntStream.range(i + 1, n)
.boxed()
.flatMap(j -> IntStream.range(j + 1, n)
.mapToObj(k -> new int[]{i, j, k})))
.filter(triplet -> {
int pos1 = posInNums2.get(nums1[triplet[0]]);
int pos2 = posInNums2.get(nums1[triplet[1]]);
int pos3 = posInNums2.get(nums1[triplet[2]]);
return pos1 < pos2 && pos2 < pos3;
})
.count();
}
}
解释
方法:
这个题解采用了一个有序集合来优化查找和插入操作。首先,使用一个数组 p 存储 nums1 中每个值的索引,使得 p[nums2[i]] 可以快速获得 nums2 中元素在 nums1 中的位置。接着,通过遍历 nums2 来构建好的三元组。对于 nums2 中的每一个元素 nums2[i](作为三元组中的 y),使用一个有序集合 s 来维护已经遍历过的 nums2 元素在 nums1 中的位置。对于每个元素 y,通过二分查找其在 s 中的位置,可以得到小于 y 的元素数量(即作为 x 的候选数量)。同时,计算出大于 y 的元素数量(即作为 z 的候选数量),这样就可以确定以 y 为中心的好三元组数量。每次循环结束时,将当前 y 加入集合 s 中,以便后续查找和统计。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在算法中,有序集合s是如何确保元素顺序的,它是基于什么数据结构实现的?
▷🦆
为什么选用SortedList而不是其他类型的数据结构,如普通列表或哈希表?
▷🦆
代码中的`less = s.bisect_left(y)`步骤是如何工作的,它返回的是什么?
▷🦆
在计算好三元组数量时,公式`ans += less * (n - 1 - y - (i - less))`是如何推导出来的?
▷