zoukankan      html  css  js  c++  java
  • 整数集和求并

    腾讯研发2013年笔试题最后一题

    A,B两个整数集合,设计一个算法求他们的交集,尽可能的高效。

    思路1:老老实实查询,对A集合中的每一个元素在B集合中查找,找到则加入并集,时间复杂度O(mn),正确但不高效。

    思路2:再审题分析,由于是集合,说明元素不重复,而整数又是个很舒服的数据结构,假设限定在C语言里的整数范围(其他情况类似),用4个Byte表示[-2^31,2^31),可以考虑使用位图法做hash,即用2^32位来对应2^32个整数。算法思路:申请2^32位共512M内存对A中的每个整数做hash,在位图中把与其对应的位置1。对B中的每个元素检查位图对应的位,如果为1则加入并集。

    时间复杂度O(m+n),空间换时间,貌似代价略大,可以考虑更换hash,允许一定概率的碰撞。

    一个简单的位图实现方法:

     1 #include<stdio.h>
     2 #define MAXN 100
     3 unsigned char hash[1<<29]={0};//注意大数组在局部中会申请失败
     4 int main()
     5 {
     6     int i,m,n,k=0;
     7     int A[MAXN]={0};
     8     int B[MAXN]={0};
     9     int intersection[MAXN]={0};
    10     printf("hello
    ");
    12     scanf("%d %d",&m,&n);
    13     for(i=0;i<m;i++){
    14         scanf("%d",&A[i]);
    15         hash[((unsigned) A[i])/8] += 0x80 >> ((unsigned)A[i] % 8);
    17     }
    18     for(i=0;i<n;i++){
    19         scanf("%d",&B[i]);
    21         if(0 != (hash[((unsigned) B[i])/8] & (0x80 >> ((unsigned)B[i] % 8)))){
    22             intersection[k]=B[i];
    23             k++;
    24         }
    25     }
    26     for (i=0;i<k;i++)
    27         printf("%d ",intersection[i]);
    28     printf("
    ");
    29     return 0;
    30 }

    扩展一下,如果是大数据下的多个集合求并集,不限元素类型,那么最好采用hash链表,为表中的每个节点设置计数器即可。当然也可以两两求并,不过效率貌似不如前者。

  • 相关阅读:
    qt creator源码全方面分析(2-10-4)
    qt creator源码全方面分析(2-10-3)
    qt creator源码全方面分析(2-10-2)
    qt creator源码全方面分析(2-10-1)
    qt creator源码全方面分析(2-9)
    flex布局使用
    filter,map,reduce三个数组高阶函数的使用
    git的使用总结
    axios学习和使用
    vuex的学习
  • 原文地址:https://www.cnblogs.com/solarya/p/3655401.html
Copyright © 2011-2022 走看看