给你一个整数数组 arr ,以及 a、b 、c 三个整数。请你统计其中好三元组的数量。
如果三元组 (arr[i], arr[j], arr[k]) 满足下列全部条件,则认为它是一个 好三元组 。
1 | 0 <= i < j < k < arr.length |
返回 好三元组的数量 。
方法一:暴力破解
三层循环
1 | public int countGoodTriplets(int[] arr, int a, int b, int c) { |
时间复杂度:$o(n^3)$
空间复杂度:0(1)
方法二:枚举优化
找出满足 |arr[j]- arr[k]|≤b
的二元组 (j,k)
中满足条件的 i 的个数。根据
1 | 0 <= i < j < k < arr.length (1) |
- 找出满足 (2),(3)等式的取值范围
[arr[j]−a,arr[j]+a]
和 [arr[k]−c,arr[k]+c]
两个区间的交集,记为 [l,r]。
- 满足(1)取值
最终的取值区间为[max(0, l), min(1000, r)]
- 建立一个关于 arr[i] 的频次数组的前缀和 sum。
每次的满足的个数为 :sum[r]−sum[l−1]
考虑怎么维护保证当前频次数组存的数的下标符合 i<j 的限制,我们只要从小到大枚举 j,每次 j 移动指针加一的时候,将 arr[j] 的值更新到 sum 数组中即可,这样能保证枚举到 j 的时候 sum 数组里存的值的下标满足限制。
1 | public int countGoodTriplets(int[] arr, int a, int b, int c) { |