leetcode 349:两个阵列的交集

时间:2016-10-14 12:04:15

标签: c algorithm

给定两个数组,编写一个函数来计算它们的交集。

实施例: 给定nums1 = [1,2,2,1],nums2 = [2,2],返回[2]。

注意:

结果中的每个元素都必须是唯一的。

结果可以是任何顺序。

我首先使用两个循环来解决这个问题,并且弹出RunTime Error,因为复杂度为O(n ^ 2)。然后,我查找了许多解决方案,但没有一个是用C语言编写的。但是,我在C ++中找到了一个使用hashset的解决方案,这个解决方案是O(m + n)复杂度。

解决方案在这里:

public class Solution {  
    public int[] intersection(int[] nums1, int[] nums2) {  
        if(nums1.length==0||nums2.length==0)  
            return new int[0];  
        Set<Integer> result = new HashSet();  
        Set<Integer> set1 = new HashSet();  
        for(int i=0;i<nums1.length;i++){  
            set1.add(nums1[i]);  
        }  
        for(int i=0;i<nums2.length;i++){  
            if(set1.contains(nums2[i]))  
                result.add(nums2[i]);  
        }  
        int[] res = new int[result.size()];  
        int i=0;  
        Iterator iter = result.iterator();  
        while(iter.hasNext()){  
            res[i++]=(int)iter.next();  
        }  
        return res;  
    }  
}  

我想在C中使用哈希表,所以我自己定义一个哈希表结构并编写一个hashFind函数来查找该值是否在哈希表中。但是,RunTime Error仍然会弹出。我想问一下问题是否源于我的hashFind函数?但是,我认为既然我定义了足够大的哈希表并且来自leetcode的给定数据不是那么大,我的算法的复杂性也应该是O(m + n)。

这是我的代码:

/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
#define HASHSIZE 1007

static int hashf(int key) {
    return key % HASHSIZE;
}

typedef struct listnode {
    int val;
    struct listnode *next;
} listnode;

typedef struct hashtable {
    listnode **hash;
} hashtable;

static hashtable *hashCreat(void) {
    hashtable *h;
    int i;

    if ((h = (hashtable *) malloc(sizeof(hashtable))) == NULL) return NULL;
    if ((h->hash = (listnode **) malloc(sizeof(listnode *) * HASHSIZE)) == NULL) return NULL;
    for (i = 0; i < HASHSIZE; i++)
        h->hash[i] = NULL;
    return h;
}

static void hashRelease(hashtable *h) {
    listnode *current, *tmp;
    int i;

    for (i = 0; i < HASHSIZE; i++) {
        current = h->hash[i];
        while (current != NULL) {
            tmp = current->next;
            free(current);
            current = tmp;
        }
    }
    free(h->hash);
    free(h);
}

static void hashInsert(hashtable *h, int key) {
    int value;
    listnode *node;
    listnode *current;

    if ((node = (listnode *) malloc(sizeof(listnode))) ==NULL) return NULL;
    value = hashf(key);
    current = h->hash[value];
    while (current != NULL) {
        if (current->val == key) return;
        current = current->next;
    }
    node->next = h->hash[value];
    h->hash[value] = node;
    node->val = key;
}

static bool hashFind(hashtable *h, int key) {
    int value;
    listnode *current;

    value = hashf(key);
    current = h->hash[value];
    while (current != NULL) {
        if (current->val = key) return 1;
        current = current->next;
    }
    return 0;
}

int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
    if (nums1Size == 0 || nums2Size == 0) return NULL;

    int *result;
    int i, j;
    int pos;
    hashtable *h;

    if ((result = (int *) malloc(sizeof(int) * *returnSize)) ==NULL) return NULL;
    h = hashCreat();
    pos = 0;
    for (i = 0; i < nums1Size; i++)
        hashInsert(h, nums1[i]);
    for (j = 0; j < nums2Size; j++)
        if (hashFind(h, nums2[j]))
            result[pos++] = nums2[j];
    hashRelease(h);
    return result;
}

提前感谢您的回答或评论。

1 个答案:

答案 0 :(得分:-1)

运行时错误表示您的代码在运行时没有正确执行和退出。它不是时间复杂度(TLE - 超出时间限制)或空间complxity(MLE - 超出内存限制)。运行时错误的原因有很多。其中,最常见的Leetcode问题是 - array out of bound。可能是您正在尝试访问容器的某个索引,该索引已超出范围。

以下是您的修改和接受的解决方案:

/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
#define HASHSIZE 1007

static int hashf(int key) {
    return key % HASHSIZE;
}

typedef struct listnode {
    int val;
    struct listnode *next;
} listnode;

typedef struct hashtable {
    listnode **hash;
} hashtable;

static hashtable *hashCreat(void) {
    hashtable *h;
    int i;

    if ((h = (hashtable *) malloc(sizeof(hashtable))) == NULL) return NULL;
    if ((h->hash = (listnode **) malloc(sizeof(listnode *) * HASHSIZE)) == NULL) return NULL;
    for (i = 0; i < HASHSIZE; i++)
        h->hash[i] = NULL;
    return h;
}

static void hashRelease(hashtable *h) {
    listnode *current, *tmp;
    int i;

    for (i = 0; i < HASHSIZE; i++) {
        current = h->hash[i];
        while (current != NULL) {
            tmp = current->next;
            free(current);
            current = tmp;
        }
    }
    free(h->hash);
    free(h);
}

static void hashInsert(hashtable *h, int key) {
    int value;
    listnode *node;
    listnode *current;

    // if ((node = (listnode *) malloc(sizeof(listnode))) ==NULL) return NULL;
    // Correction: You can't return NULL from a void function
    if ((node = (listnode *) malloc(sizeof(listnode))) ==NULL) return;
    value = hashf(key);
    current = h->hash[value];
    while (current != NULL) {
        if (current->val == key) return;
        current = current->next;
    }
    node->next = h->hash[value];
    h->hash[value] = node;
    node->val = key;
}

static bool hashFind(hashtable *h, int key) {
    int value;
    listnode *current;

    value = hashf(key);
    current = h->hash[value];
    while (current != NULL) {
        // if (current->val = key) return 1;
        // Correction: == instead of =
        if (current->val == key) return 1;
        current = current->next;
    }
    return 0;
}

int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
    if (nums1Size == 0 || nums2Size == 0) return NULL;

    int* result;
    int i, j;
    int pos;
    hashtable *h;
    // you need another hash to check if intersection array is including duplicate elements
    hashtable *h2;

    // if ((result = (int *) malloc(sizeof(int) * *returnSize)) ==NULL) return NULL;
    // Correction: returnSize is the size of result array you have to return. Allocate minimum of two input array length as intersection array can't be bigger than smaller array
    int minLength = (nums1Size < nums2Size ? nums1Size : nums2Size);
    if ((result = (int *) malloc(sizeof(int) * (minLength + 1))) ==NULL) return NULL;
    h = hashCreat();
    h2 = hashCreat();
    pos = 0;
    for (i = 0; i < nums1Size; i++)
        hashInsert(h, nums1[i]);
    for (j = 0; j < nums2Size; j++)
        if (hashFind(h, nums2[j])) {
            // check if current element is already included or not
            if(!hashFind(h2, nums2[j])) {
                result[pos++] = nums2[j];
                hashInsert(h2, nums2[j]);
            }
        }
    hashRelease(h);
    hashRelease(h2);

    *returnSize = pos; // set the result array size which will be returned to caller as pass by reference
    return result;
}

事实是 - 你在面试中没有机会实现自己的哈希表。因此,您应该学习并使用一些高级语言,如C ++,它们在标准库中具有这些数据结构。