📌  相关文章
📜  计算不同元素数组中的三元组 (i, j, k),使得 a[i] < a[j] > a[k] 和 i < j < k

📅  最后修改于: 2021-09-05 08:54:51             🧑  作者: Mango

给定一个由N 个不同整数组成的数组 arr[] ,任务是计算数组arr[] 中可能的三元组 (i, j, k)的数量,使得i < j < karr[i] < arr[ j] > arr[k]

例子:

朴素方法:解决问题的最简单方法是遍历给定数组,对于每个元素arr[i] ,将 arr[i] 左侧较小元素的计数与 arr[i]左侧较小元素的计数的乘积arr[i] 的右侧给出元素 arr[i]作为中间元素的三元组数。为每个索引获得的所有计数的总和是所需的有效三元组数。
时间复杂度: O(N 2 )
辅助空间: O(1)

高效的方法:上述方法也可以通过使用基于策略的数据结构 ( PBDS)找到较小元素的数量来优化。请按照以下步骤解决问题:

  • 初始化变量,将ans设为0 ,以存储可能对的总数。
  • 初始化基于策略的数据结构的两个容器,比如PQ
  • 初始化成对向量V ,其中V[i]。 firstV[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