为了实现这个功能,我们需要找到满足条件的三元组 (i, j, k),使得:
0 <= i < j < k < n,即i、j和k是不同的,并且按顺序排列。max(a[i], a[j], a[k]) - min(a[i], a[j], a[k]) = 1,即三元组中的最大值与最小值之差为 1。
思路:
- 我们可以直接遍历数组中的所有可能的三元组
(i, j, k)。 - 对每个三元组,我们计算它们的最大值和最小值,检查是否满足
max(a[i], a[j], a[k]) - min(a[i], a[j], a[k]) == 1。 - 如果满足条件,则计数。
优化建议:
我们可以优化一下这个过程,避免重复计算和遍历所有三元组。通过记录数组中每个元素的数量,可以快速判断符合条件的三元组。
代码实现:
ini
代码解读
复制代码
cpp
Copy code
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
long long solution(vector<int> a) {
long long count = 0;
int n = a.size();
// 遍历所有可能的三元组 (i, j, k)
for (int i = 0; i < n - 2; ++i) {
for (int j = i + 1; j < n - 1; ++j) {
for (int k = j + 1; k < n; ++k) {
int maxVal = max({a[i], a[j], a[k]});
int minVal = min({a[i], a[j], a[k]});
if (maxVal - minVal == 1) {
count++;
}
}
}
}
return count;
}
int main() {
vector<int> a1 = {2, 2, 3, 1};
vector<int> a2 = {1, 3, 2, 2, 1};
vector<int> a3 = {1, 3, 2, 2, 1, 2};
cout << (solution(a1) == 2) << endl; // 输出1表示正确
cout << (solution(a2) == 5) << endl; // 输出1表示正确
cout << (solution(a3) == 12) << endl; // 输出1表示正确
return 0;
}
解释:
solution函数通过三个嵌套循环遍历所有可能的三元组(i, j, k),并计算每个三元组的最大值和最小值。- 如果最大值与最小值之差为1,则计数器
count增加。 - 在
main函数中,我们通过比较返回值与预期值,来验证程序是否正确。
复杂度:
这个实现的时间复杂度是 O(n^3),因为我们有三重嵌套循环来遍历所有的三元组。对于大数组,这种算法可能会较慢。
改进方向:
如果数组的大小很大,我们可以考虑其他更高效的算法,例如通过哈希表或计数排序来优化,避免直接遍历所有三元组。
要优化这个问题,目标是尽量减少不必要的计算,避免三重循环导致的 O(n^3) 时间复杂度。我们可以考虑以下优化方法:
1. 使用计数法
通过统计每个数值在数组中的出现频率,可以大大减少计算量。具体来说,可以利用以下观察:
- 我们只关心三元组中的最大值和最小值之差为 1。
- 因此,只需统计数组中出现的数字,并查看哪些数字相差为 1。例如,如果
x出现了count[x]次,且x+1出现了count[x+1]次,那么可能的三元组(i, j, k)就是从这两个数字中挑选出合适的三个数字来。
2. 通过两个数字的计数,找到符合条件的三元组
对于每个数字 x,检查数组中数字 x 和 x+1 的组合。具体来说:
- 如果数组中
x出现了cnt_x次,x+1出现了cnt_x_plus_1次,那么所有符合条件的三元组(i, j, k)可以通过这两个数字来构成。