我有2个int数组我需要在O(nlogn)中打印所有相同的整数 数组未排序,排序后可以是:
X [ 1,2,3,4,5,6,7,8,9]
Y [1,2,8,9]
所以只检查4个地方(较小数组的大小)不是一个选项。
我需要使用什么样的循环\方程,因此它将是nlogn ? 如果我将运行for到最小值的最后一个值 - 它仍将是nlogn- 我如何才能在没有运行直到结束时才到达arraya中的最后一个整数?
答案 0 :(得分:4)
我希望这足以暗示......
对阵列进行排序后,只需并排遍历阵列即可。跟踪每个数组的“当前”元素(X
和Y
)。您可以使用每个数组的索引变量或使用指针来执行此操作。就个人而言,我发现使用指针更容易,但您或您的朋友可能有不同的偏好。
对于每对“当前”元素,如果元素匹配,则打印该值。然后考虑需要做什么,如果有的话,移动到每个数组的下一个元素(对于元素不匹配的情况以及它们匹配的情况)。只有三种情况:
x[cur_x] == y[cur_y]
x[cur_x] < y[cur_y]
y[cur_y] < x[cur_x]
所以确定在每种情况下应该做什么都不应该太难。
在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)
此方法不需要对X
和Y
进行排序。
将X
的元素添加到二叉搜索树(避免重复条目,即如果X[0] = 1
和X[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;
}