2475. Number of Unequal Triplets in Array

题目 #

You are given a 0-indexed array of positive integers nums. Find the number of triplets (i, j, k) that meet the following conditions:

  • 0 <= i < j < k < nums.length
  • nums[i], nums[j], and nums[k] are pairwise distinct.
    • In other words, nums[i] != nums[j], nums[i] != nums[k], and nums[j] != nums[k].

Return the number of triplets that meet the conditions.

Example 1:

Input: nums = [4,4,2,4,3]
Output: 3
Explanation: The following triplets meet the conditions:
- (0, 2, 4) because 4 != 2 != 3
- (1, 2, 4) because 4 != 2 != 3
- (2, 3, 4) because 2 != 4 != 3
Since there are 3 triplets, we return 3.
Note that (2, 0, 4) is not a valid triplet because 2 > 0.

Example 2:

Input: nums = [1,1,1,1,1]
Output: 0
Explanation: No triplets meet the conditions so we return 0.

Constraints:

  • 3 <= nums.length <= 100
  • 1 <= nums[i] <= 1000

思路1 爆破 #

分析 #

  • 照着做

代码 #

 1func unequalTriplets(nums []int) int {
 2	result := 0
 3	for i := 0; i < len(nums)-2; i++ {
 4		for j := i + 1; j < len(nums)-1; j++ {
 5			if nums[j] == nums[i] {
 6				continue
 7			}
 8			for k := j + 1; k < len(nums); k++ {
 9				if nums[k] == nums[j] || nums[k] == nums[i] {
10					continue
11				}
12				result++
13			}
14		}
15	}
16	return result
17}

思路2 排序+分组 #

分析 #

  • 只要数量,那么顺序就无所谓了,那么先排序
  • 排完序之后可以认为中间的数是x,那么小于x的有a个,x有b个,大于x的有c个,x在中间的数对有abc个

代码 #

 1func unequalTriplets1(nums []int) int {
 2	sort.Ints(nums)
 3	n := len(nums)
 4	// x作为中间的数,那么小于x的有a个,x有b个,大于x的有c个,x在中间的数对有abc个
 5	start, res := 0, 0 // start为x的起始位置
 6	for i, x := range nums[:n-1] {
 7		if x != nums[i+1] {
 8			res += start * (i + 1 - start) * (n - i - 1)
 9			start = i + 1
10		}
11	}
12	return res
13}

思路3 分组+计算 #

分析 #

  • 思路和上面一样,不过排完序再算abc不太优雅,用分组来直接统计数量更好
  • 使用hashmap来统计

代码 #

 1func unequalTriplets2(nums []int) int {
 2	h := make(map[int]int)
 3	for _, v := range nums {
 4		h[v]++
 5	}
 6	a, c, res := 0, len(nums), 0
 7	for _, b := range h {
 8		c -= b
 9		res += a * b * c
10		a += b
11	}
12	return res
13}