给定一个由N 个不同整数组成的数组 arr[] ,任务是计算数组arr[] 中可能的三元组 (i, j, k)的数量,使得i < j < k和arr[i] < arr[ j] > arr[k] 。
例子:
Input: arr[] = {2, 3, 1, -1}
Output: 2
Explanation: From the given array, all possible triplets satisfying the property (i, j, k) and arr[i] < arr[j] > arr[k] are:
- (0, 1, 2): arr[0](= 2) < arr[1](= 3) > arr[2](= 1).
- (0, 1, 3): arr[0](= 2) < arr[1](= 3) > arr[3](= -1).
Therefore, the count of triplets is 2.
Input: arr[] = {2, 3, 4, 6, 7, 9, 1, 12, 10, 8}
Output: 41
朴素方法:解决问题的最简单方法是遍历给定数组,对于每个元素arr[i] ,将 arr[i] 左侧较小元素的计数与 arr[i]左侧较小元素的计数的乘积arr[i] 的右侧给出元素 arr[i]作为中间元素的三元组数。为每个索引获得的所有计数的总和是所需的有效三元组数。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:上述方法也可以通过使用基于策略的数据结构 ( PBDS)找到较小元素的数量来优化。请按照以下步骤解决问题:
- 初始化变量,将ans设为0 ,以存储可能对的总数。
- 初始化基于策略的数据结构的两个容器,比如P和Q 。
- 初始化成对向量V ,其中V[i]。 first和V[i].second存储每个数组元素 arr[i]左侧和右侧的较小元素的计数。
- 遍历给定数组,对于每个元素arr[i] ,将 V[i] .first 的值更新为P.order_of_key(arr[i])并插入arr[i]以设置P 。
- 从右到左遍历数组,对于每个元素arr[i] ,将 V[i] .first 的值更新为P.order_of_key(arr[i])并插入arr[i]以设置Q 。
- 遍历对V的向量并将V[i].first * V[i].second的值添加到变量 ans 。
- 完成以上步骤后,打印ans的值作为总对数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#include
#include
#include
using namespace __gnu_pbds;
using namespace std;
// Function to find the count of triplets
// satisfying the given conditions
void findTriplets(int arr[], int n)
{
// Stores the total count of pairs
int ans = 0;
// Declare the set
tree, rb_tree_tag,
tree_order_statistics_node_update>
p, q;
// Declare the vector of pairs
vector > v(n);
// Iterate over the array from
// left to right
for (int i = 0; i < n; i++) {
// Find the index of element
// in sorted array
int index = p.order_of_key(arr[i]);
// Assign to the left
v[i].first = index;
// Insert into the set
p.insert(arr[i]);
}
// Iterate from right to left
for (int i = n - 1; i >= 0; i--) {
// Find the index of element
// in the sorted array
int index = q.order_of_key(arr[i]);
// Assign to the right
v[i].second = index;
// Insert into the set
q.insert(arr[i]);
}
// Traverse the vector of pairs
for (int i = 0; i < n; i++) {
ans += (v[i].first * v[i].second);
}
// Print the total count
cout << ans;
}
// Driver Code
int main()
{
int arr[] = { 2, 3, 1, -1 };
int N = sizeof(arr) / sizeof(arr[0]);
findTriplets(arr, N);
return 0;
}
2
时间复杂度: O(N * log N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live