繁体   English   中英

如何从三个排序的 A、B、C 中找到三元组 { x, y, z },使得 x < y < z 在 O(n) 中?

[英]How to find triplets { x , y , z } from three sorted A, B, C such that x < y < z in O(n)?

假设我有三个排序的 arrays

答:{ 4, 9 }

B: { 2, 11}

C: { 12, 14}

那么三元组的数量 { x, y, z } 使得 x 属于 A,y 属于 B 并且 z 属于 C 使得 x < y < z 是 -> 4

我知道 O(n ^3) 算法,但如何在 O(n) 中做到这一点。 其中 n 是数组的长度。

将“计数”变量初始化为零。

如果没有给出,则在线性时间内找到三个列表的长度。

在线性时间内将三个列表合并为一个排序列表,跟踪每个列表属于哪个原始列表。

解析合并列表。 当你这样做时,跟踪你看到的 A 中的元素数量,以及你没有看到的 C 中的元素数量。 每次遇到列表 B 中的成员时,将计数增加 (A seen) * (C not seen),两者都是当前索引。 我们在这里所做的是,对于来自 B 的元素,计算我们可以从 A 中找到较小元素和从 C 中找到较大元素的方法的数量。

您还可以跟踪 B 并在合并列表中的最后一个之后停止。

上)

例如,A:{ 4, 9 }

B: { 2, 11}

C: { 12, 14}

(2,B), (4,A), (9,A), (11,B), (12,C), (14,C)

initialize: count = 0, A_seen = 0, C_unseen=2
index 0: A_seen = 0, C_unseen = 2, count = 0 + 0*2 = 0
index 1: A_seen = 1, C unseen = 2, count unchanged
index 2: A_seen = 2, C unseen = 2, count unchanged
index 3: A_seen = 2, C unseen = 2, count = 0 + 2*2 = 4
We can stop here since we're out of B's.

- 编辑 -

轻松优化:不合并列表,只遍历 B,跟踪 A 的最大较小元素和 C 的最小较大元素的索引,然后像以前一样继续。 这仍然是线性的并且开销更少。

您可以使用带有二进制搜索的记忆计数来做到这一点。复杂性: O(n * logn)

对于 B 的每个元素,从数组 C 中搜索更大的值 position。 然后您可以计算有效 y < z 的数量。 它将是(n - position 的价值更大)

现在,对于 A 的每个元素,从数组 B 中搜索更大的值 position。然后您可以计算有效 x < y 的数量。 它将是(n - position 的值更大)..这里您需要计算 B 的每个有效 position 的计数总和。

示例代码在这里:

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

int bs(int l, int h, int v, int A[]) {
    int m;
    while (l <= h) {
        m = (l + h) / 2;
        if (A[m] < v) {
            l = m + 1;
        } else {
            h = m - 1;
        }
    }
    return l;
}

int main() {
    int A[] = {4,9};
    int B[] = {2,11};
    int C[] = {12,14};
    int dp[] = {0};
    int n = 2, i, ans = 0, p;
    for (i = 0; i < n; i++) {
        p = bs(0, n-1, B[i], C);
        dp[i] = i ? dp[i-1] + n-p : n-p;
    }
    for (i = 0; i < n; i++) {
        p = bs(0,n-1, A[i], B);
        if (p) {
            ans += (dp[n-1]-dp[p-1]);
        } else {
            ans += dp[n-1];
        }
    }
    printf("%d\n", ans);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM