比较排序的数组 - nlogn

时间:2012-01-04 06:36:37

标签: c

我有2个int数组我需要在O(nlogn)中打印所有相同的整数 数组未排序,排序后可以是:

X [ 1,2,3,4,5,6,7,8,9]
Y [1,2,8,9]

所以只检查4个地方(较小数组的大小)不是一个选项。

我需要使用什么样的循环\方程,因此它将是nlogn ? 如果我将运行for到最小值的最后一个值 - 它仍将是nlogn- 我如何才能在没有运行直到结束时才到达arraya中的最后一个整数?

4 个答案:

答案 0 :(得分:4)

我希望这足以暗示......

对阵列进行排序后,只需并排遍历阵列即可。跟踪每个数组的“当前”元素(XY)。您可以使用每个数组的索引变量或使用指针来执行此操作。就个人而言,我发现使用指针更容易,但您或您的朋友可能有不同的偏好。

对于每对“当前”元素,如果元素匹配,则打印该值。然后考虑需要做什么,如果有的话,移动到每个数组的下一个元素(对于元素不匹配的情况以及它们匹配的情况)。只有三种情况:

  1. x[cur_x] == y[cur_y]
  2. x[cur_x] < y[cur_y]
  3. y[cur_y] < x[cur_x]
  4. 所以确定在每种情况下应该做什么都不应该太难。

    在O(n log n)操作中对数组进行排序。遍历数组是一个O(n)操作,所以它总是一个O(n)+ O(n log n)操作,它减少到O(n log n)。换句话说,操作的总体时间复杂度由排序操作决定。

    使用二进制搜索也可以工作,但它可能稍微复杂一些 - 特别是如果需要(并根据要求可能意味着“正确”),正确处理数组中的重复元素。 / p>

答案 1 :(得分:3)

您可以使用较小的数组并使用二进制搜索

搜索较大元素中的每个元素
for(int i = 0; i < size1; i++) {     
  binarysearch(arr_small[i], arr_big);
}

二进制搜索每次搜索需要O(log n)时间。所有元素的总搜索时间为O(nlogn)

如果您不记得二元搜索,请参阅链接:http://en.literateprograms.org/Binary_search_(C

答案 2 :(得分:2)

在哈希中抛出一个数组。在哈希中查找其他数组。但那不是nlogn ..它是m + n。

答案 3 :(得分:1)

此方法不需要对XY进行排序。

X的元素添加到二叉搜索树(避免重复条目,即如果X[0] = 1X[1] = 1则不添加X[1];只需忽略它)

然后尝试将Y的内容添加到同一个二叉搜索树中。如果您发现该元素已存在,那么它的相同。

总时间复杂度归结为向BST添加元素的时间复杂度O(n log n),但如果树偏斜(即如果数组已排序),最坏情况将是O(n)


以下是供您参考的代码!

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>

typedef struct node {
        int data;
        struct node *left;
        struct node *right;
} NODE;

NODE *root = NULL;

NODE * newnode (int data)
{
        NODE * n = NULL;
        if (n = (NODE *) malloc (sizeof (NODE))) {
                n->data = data;
                n->right = n->left = NULL;
        } else {
                printf("%d - %d - unalbe to create new node \n", __LINE__, data);
        }

        return n;
}

NODE * getnode(NODE * n, int data)
{
        if (n == NULL)
                return NULL;

        if (n->data == data)
                return n;

        if (data < n->data)     {
                return getnode (n->left, data);
        }

        if (data > n->data) {
                return getnode (n->right, data);
        }

        return NULL;
}

NODE * insert (NODE * node, int data, int *dup)
{
    NODE * n = NULL;

    if (node != NULL) {
        if (getnode(node, data) != NULL) {
            /* element already present in the tree..
               so set the dup and return the root */
            *dup = 1;
            return node;
        }
    }

    if (node == NULL) {
        n = newnode(data);
        return (n);
    }

    if (data <= node->data)
        node->left = insert(node->left, data, dup);
    else
        node->right = insert(node->right, data, dup);

    return node;
}

NODE * deletetree(NODE * from)
{
    if (from != NULL) {
        deletetree(from->left);
        deletetree(from->right);
        //printf("deleting %d \n", from->data);
        free(from);
    }
    return NULL;
}

int main()
{
    int sum = 35;
    int X[] = {1,2,3,4,5,6,7,8,9,1,2,3,4,5};
    int Y[] = {1,2,8,9};
    int i, dup = 0;

    int xlen = sizeof(X)/sizeof(X[0]);
    int ylen = sizeof(Y)/sizeof(Y[0]);

    printf("len of X is : %d \n", xlen);
    printf("len of Y is : %d \n", ylen);

    NODE * root1 = NULL;

    for (i=0; i<xlen; i++) {
        root = insert(root, X[i], &dup);
    }

    for (i=0; i<ylen; i++) {
        dup = 0;
        root = insert(root, Y[i], &dup);
        if (dup == 1) {
            printf("%d ", Y[i]);
        }
    }

    printf("\n");
    root = deletetree(root);

    return 0;
}