C++ 求数组中三元组(i,j,k)的数目,使A[i]+;A[j]=2*A[k]

C++ 求数组中三元组(i,j,k)的数目,使A[i]+;A[j]=2*A[k],c++,math,C++,Math,如何在数组中查找元组/对i、j、k的数量,使a[i]+a[j]=2*a[k]。复杂度应该是O(n*logn)或O(n),因为n>i; 排序(a.begin(),a.end()); int-sol=0; 对于(int i=0;i J-I 甚至在中间有一个合适的元素,计数是“代码>O(n))< /C> > */P> O(N²)解决方案如下: 对阵列进行逐级排序 对于每个i 设置k=i,对于每个j>i 增量k直到2a[k]>=A[i]+A[j] 如果达到相等,则增加计数 对于给定的i,j

如何在数组中查找元组/对i、j、k的数量,使a[i]+a[j]=2*a[k]。复杂度应该是O(n*logn)或O(n),因为n>i; 排序(a.begin(),a.end()); int-sol=0; 对于(int i=0;iCuth

复杂性不可能比O(n席)好,因为在元素构成一个单程运算的情况下,所有的配对<代码>(i,j)< /> > <代码> J-I 甚至在中间有一个合适的元素,计数是“代码>O(n))< /C> > */P>

O(N²)
解决方案如下:

  • 对阵列进行逐级排序

  • 对于每个
    i

    • 设置
      k=i
      ,对于每个
      j>i

      • 增量
        k
        直到
        2a[k]>=A[i]+A[j]

      • 如果达到相等,则增加计数

对于给定的
i
j
k
单调增加到
N
,因此操作总数为
O(N-i)
。这证明了全局行为是最优的


*这里有一点微妙之处,因为你可能会反驳这个论点,声称:“我们可以确定数组在时间
O(N)
中形成一个算术序列,并由此计算一次过的计数”

但是如果不是一个单一的算术序列,而是两个长度
N/2
,那么即使它们相互交织,计数的二次行为仍然存在。至少有
N
方法可以将两个算术序列交织在一起


如果元素的范围远小于它们的数量,则通过直方图压缩数据是有利的


由于
k
系统地
(i+j)/2
,三重检测算法稍微简化了一点。现在,每三个字符就代表
Hi.Hk.Hj
,而不是
1
。复杂性是
O(M²)
,其中
M
是直方图的大小。

我们调用
D
-数组中不同值的总数。如果
abs(a[i])是
i==j==k
一个有效答案,或者是否存在其他约束条件?到目前为止你试过什么?这不是一个代码编写网站。看起来你可以使用一些
来进行
循环。@RichardCritten值“在数组中”,这不仅仅是指你通过将
a
按值传递到函数中来进行大量不必要的复制。对于每个
i!=j
compute
a[i]+i[j]
。如果是奇数,则不存在
k
。否则,搜索数组以查找等于
(a[i]+i[j])/2
的元素。如果有的话,你有一个解决方案。您可能还想限制以下问题:数组元素是否唯一?数组是否已排序?[您的代码似乎试图使用二进制搜索,这表明数组至少已排序,但问题中未指定该排序]。我可能错了,但O(n^2)太慢了。我有一个n^2代码(我写的那一个),但不要认为这会足够快,因为n@Morgana:你的代码是O(n²logn),而不是O(n²)。如果你相信我的论点,在最坏的情况下,速度不可能超过O(N²)。我忘了一件重要的事情要说!我没看到。。。abs(a[i)]@Morgana:是的,有了这些信息,问题就大不相同了,解决方案可能是基于直方图的。我不太确定,我怎么能在这方面使用直方图?
#include <bits/stdc++.h>

using namespace std;

int binarna(vector<int> a, int k){
    int n = a.size();
    int low = 0, high = n - 1; 
    bool b = false;

    int mid;
    while(low <= high){
        mid = (low + high) / 2;

        if (a[mid] == k){
            b = true;
            break;
        }

        if (k < a[mid])
            high = mid - 1;
        else
            low = mid + 1;
    }

    if (b)
        return mid;
    else
        return -1;
}


int main()
{
    int n;
    cin >> n;

    vector<int> a(n);
    for (auto& i : a)
        cin >> i;

    sort(a.begin(), a.end());

    int sol = 0;
    for (int i = 0; i < n - 1; ++i){
        for (int j = i + 1; j < n; ++j){
            if ((a[i] + a[j]) % 2)
                continue;
            int k = (a[i] + a[j]) / 2;

            if (binarna(a, k) != -1)
                ++sol;
        }
    }

    cout << sol << '\n';
}
2*B[k].value == B[i].value + B[j].value
totalCount += B[k].count * B[i].count * B[j].count
2*A[k].value == A[i].value + A[j].value