在数组中查找不平衡点

时间:2019-03-31 08:04:12

标签: c++ algorithm

给出一个数组,对于每个元素我们必须计算两个值LL和RR。 LL =特定数组元素左侧小于它的元素数。 RR =特定数组元素右边的元素数大于 我们需要从数组中找到absolute(LL-RR)的最大值。 解决了o(n ^ 2)但想要O(n)或O(nlogn)方法。
输入:1 5
        1 2 1 3 4
输出:4

#include<bits/stdc++.h>
using namespace std;


int main()
{
int t;
cin>>t;
while(t--)
{
 int n;
 cin>>n;
 int a[n];
 for(int i=0;i<n;i++)cin>>a[i];
 int ll=0;
 int rr=0;
 int mx=INT_MIN;
  for(int i=0;i<n;i++)
  {
   ll=rr=0;
   for(int j=i-1;j>=0;j--)
   {
    if(a[j]<a[i])ll++;
   }

   for(int k=i+1;k<n;k++)
   {
     if(a[k]>a[i])rr++;

   }
    int t=abs(ll-rr);
    if(t>mx)mx=t;


  }
  cout<<mx<<endl;



}




}

1 个答案:

答案 0 :(得分:0)

首先摆脱:

#include<bits/stdc++.h>  // non standard
using namespace std; // will cause name collision in the future.

相反,请包括您需要的内容:

#include <iostream>

并使用std::前缀,如:。

std::cout << mx << std::endl;

要提高您的复杂性,请考虑您的目标以及现在如何实现这些目标。

目前,您可以通过线性遍历所有小于a [i]的元素来计算元素。您需要一个可以在O(log i)中而不是在O(i)中回答的数据结构。

一种可能性是一棵红黑树,该树会计算每个子树中的节点数。

从左到右遍历数组。将每个元素插入rb-tree,更新每个a [i]的计数为O(log i)。从插入的节点到根,每次您从右边到达时:将左边的计数加1。这得到LL,并且对于每个a [i]都以O(log i)起作用。

对于RR,请执行相反的操作。从右到左执行相同的操作,但是对取反的值进行操作(这样,可以很容易地重用相同的rb-tree代码)。将计数存储在RR数组中。