难度简单30
给你一个下标从 0 开始的正整数数组 nums
。请你找出并统计满足下述条件的三元组 (i, j, k)
的数目:
0 <= i < j < k < nums.length
nums[i]
、 nums[j]
和 nums[k]
两两不同。
nums[i] != nums[j]
、nums[i] != nums[k]
且 nums[j] != nums[k]
。返回满足上述条件三元组的数目*。*
示例 1:
输入:nums = [4,4,2,4,3]
输出:3
解释:下面列出的三元组均满足题目条件:
- (0, 2, 4) 因为 4 != 2 != 3
- (1, 2, 4) 因为 4 != 2 != 3
- (2, 3, 4) 因为 2 != 4 != 3
共计 3 个三元组,返回 3 。
注意 (2, 0, 4) 不是有效的三元组,因为 2 > 0 。
示例 2:
输入:nums = [1,1,1,1,1]
输出:0
解释:不存在满足条件的三元组,所以返回 0 。
提示:
3 <= nums.length <= 100
1 <= nums[i] <= 1000
class Solution:
def unequalTriplets(self, nums: List[int]) -> int:
ans = 0
n = len(nums)
for i in range(n-2):
for j in range(i+1, n-1):
for k in range(j+1, n):
if nums[i] != nums[j] and nums[i] != nums[k] and nums[j] != nums[k]:
ans += 1
return ans
https://leetcode.cn/problems/number-of-unequal-triplets-in-array/solution/fei-bao-li-zuo-fa-by-endlesscheng-9ekp/
对于 x,设:
小于 x 的数有 a 个;
等于 x 的数有 b 个;
大于 x 的数有 c 个。
那么 x 对答案的贡献是 abc。
累加所有贡献,得到答案。通过排序,可以快速得到abc
class Solution {
public int unequalTriplets(int[] nums) {
Arrays.sort(nums);
int ans = 0, start = 0, n = nums.length;
for(int i = 0; i < n-1; i++){
if(nums[i+1] != nums[i]){
ans += start * (i - start + 1) * (n - 1 - i);
start = i+1;
}
}
return ans;
}
}
由于元素的位置是不重要的,我们可以直接用哈希表统计,方法一中的 a b c 重定义为:
在 x 之前遍历过的数有 a 个;
(当前遍历的)等于 x 的数有 b 个;
在 x 之后遍历过的数有 c 个。
class Solution {
public int unequalTriplets(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for(int num : nums){
map.put(num, map.getOrDefault(num, 0) + 1);
}
int a = 0, c = nums.length;
int ans = 0;
// 枚举中间元素的个数b,左侧元素个数记为a,右侧元素个数记为c
// 此时符合条件的三元组数量为 a x b x c
// 更新a = a + b , c = c - b
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
c -= entry.getValue();
ans += a * entry.getValue() * c;
a += entry.getValue();
}
return ans;
}
}