leetcode刷题笔记——350.两个数组的交集 Ⅱ

题目描述

leetcode刷题笔记——350.两个数组的交集 Ⅱ_第1张图片

分析

快排&双指针

描述

原来给的数组是没有排序的,快排后时间复杂度为O(MlogM+NlogN)。然后利用双指针,时间复杂度为O(M+N)。因此总时间复杂度为O(MlogM+NlogN)。

由于一开始不知道交集的元素个数,因此需要开出大小为min{m,n}的空间来暂时存储返回值,计数后再存入目标数组中。空间复杂度为O(min{m,n})。

※若c++可以直接创建一个vector(?),不需要额外数组,时间复杂度可降低为为O(1)。

代码

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int cmp(const void *a,const void *b){
    return (*(int*)a-*(int*)b);
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    qsort(nums1,nums1Size,sizeof(int),cmp);
    qsort(nums2,nums2Size,sizeof(int),cmp);
    int *tmp;
    tmp = (int*)malloc(sizeof(int)*(nums1Size+nums2Size));
    int pos1=0,pos2=0,pos=0;
    while(pos1<nums1Size&&pos2<nums2Size){
        if(nums1[pos1]>nums2[pos2]){
            pos2++;
        }
        else if(nums1[pos1]<nums2[pos2]){
            pos1++;
        }
        else{
            tmp[pos++]=nums1[pos1];
            pos1++;
            pos2++;
        }
    }
    int *ret = (int*)malloc(sizeof(int)*pos);
    for(int i=0;i<pos;i++){
        ret[i]=tmp[i];
    }
    free(tmp);
    *returnSize=pos;
    return ret; 
}

哈希表

描述

需要注意的是,由于同一个数字可能会在一个数组中出现多次,因此哈希表还需要存储其出现的此处(在val域中)。而在遍历另一个数组时,若在哈希表中查询到相同元素则在目标数组中存储,并且将哈希表val值减一

※为了降低空间复杂度,应该先遍历元素较少的那个数组,使得哈希表的长度减少。

※在将数组中元素加入哈希表时,需要将val域初始化为1。并且在第二个数组查找哈希表时,需要注意条件其val域不能为0,因为0代表在第二个数组中已经找到同等数量的相同元素加入ret数组中,而题目要求出现次数取较小值。

代码

struct hashList{
    int id;
    int val;
    UT_hash_handle hh;
};
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    struct hashList *set = NULL;
    int i;
    for(i=0;i<nums1Size;i++){
        struct hashList *tmp;
        HASH_FIND_INT(set,nums1+i,tmp);
        if(tmp!=NULL){
            tmp->val++;
        }
        else{
            tmp = malloc(sizeof(struct hashList));
            tmp->id = nums1[i];
            tmp->val = 1;
            HASH_ADD_INT(set,id,tmp);
        }
    }
    int *ret = (int *)malloc(sizeof(int)*(nums1Size+nums2Size));
    int count=0;
    for(i=0;i<nums2Size;i++){
        struct hashList *tmp;
        HASH_FIND_INT(set,nums2+i,tmp);
        if(tmp!=NULL){
            if(tmp->val != 0){
                ret[count++]=tmp->id;
                tmp->val--;
            }
        }
    }
    *returnSize = count;
    return ret;
}

收获

快排

对于快排的使用能够第一时间反应过来:用一种时间复杂度为O(NlogN)的排序算法来降低算法的整体时间复杂度。

哈希表

在数组遍历题目中,还是忽视了哈希表的适用性,其实哈希表在数组中还是一种非常实用的算法,通常能将时间复杂度化为O(N),是一种牺牲空间复杂度来换取时间复杂度的方法。
排序算法来降低算法的整体时间复杂度。

哈希表

在数组遍历题目中,还是忽视了哈希表的适用性,其实哈希表在数组中还是一种非常实用的算法,通常能将时间复杂度化为O(N),是一种牺牲空间复杂度来换取时间复杂度的方法。

你可能感兴趣的:(刷题笔记,leetcode,算法,排序算法)