跳到主要内容

923.三数之和的多种可能

链接:923.三数之和的多种可能
难度:Medium
标签:数组、哈希表、双指针、计数、排序
简介:给定一个整数数组  arr ,以及一个整数  target  作为目标值,返回满足 i < j < k 且  arr[i] + arr[j] + arr[k] == target  的元组  i, j, k  的数量。

题解 1 - cpp

  • 编辑时间:2022-03-07
  • 执行用时:12ms
  • 内存消耗:10.6MB
  • 编程语言:cpp
  • 解法介绍:合并重复元素,通过双指针查找第三个数出现的次数。
class Solution {
public:
static const int mod = 1e9 + 7;
// 三个数一样时, 从n个数中排列组合3个
int comp1(int num) { return (1 + num) * num / 2; }
// 两个数一样时, 从n个数中排列组合2个
int comp2(int num) {
int ans = 0;
for (int i = 1, n = num; i <= n; i++, num--)
ans = (ans + num * i) % mod;
return ans;
}
int threeSumMulti(vector<int> &arr, int target) {
map<int, int> m;
for (auto &num : arr) m[num]++;
vector<int> list;
for (auto &item : m) list.push_back(item.first);
int ans = 0, n = list.size();
for (int i = 0; i < n; i++) {
int num1 = list[i];
for (int j = i; j < n; j++) {
int num2 = list[j], num3 = target - num2 - num1, sum;
if (num3 < num2) break;
if (num1 == num2 && num1 == num3) {
sum = comp2(m[num1] - 2);
} else if (num1 == num2 && num1 != num3) {
sum = comp1(m[num1] - 1) * m[num3];
} else if (num1 != num2 && num2 == num3) {
sum = m[num1] * comp1(m[num2] - 1);
} else {
sum = m[num1] * m[num2] * m[num3];
}
ans = (ans + sum) % mod;
}
}
return ans;
}
};