• 整数集和求并


    腾讯研发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链表,为表中的每个节点设置计数器即可。当然也可以两两求并,不过效率貌似不如前者。

  • 相关阅读:
    asp.net 页面生命周期事件详细
    linux服务nfs与dhcp篇
    linux服务samba与ftp篇
    官网Android离线文档下载
    Android发布apk后解决百度地图不显示的问题
    win10和office2013激活
    Android-Intent and Intent Filters
    Android设置透明状态
    Android获取屏幕大小(Px)
    我的java web之路(JSP基本语法)
  • 原文地址:https://www.cnblogs.com/solarya/p/3655401.html
Copyright © 2020-2023  润新知