10.百度最新面试题:现在有1千万个随机数,随机数的范围在1到1亿之间。现在要求写出一种算法,将1到1亿之间没有在随机数中的数求出来。

10.百度最新面试题:现在有1千万个随机数,随机数的范围在1到1亿之间。现在要求写出一种算法,将1到1亿之间没有在随机数中的数求出来。

(编程珠玑上有此类似的一题,如果有足够的内存的话可以用位图法,即开一个1亿位的bitset,内存为100m/8== 12.5m, 然后如果一个数有出现,对应的bitset上标记为1,最后统计bitset上为0的即可。)

转 http://blog.csdn.net/iamsheldon/article/details/6860774

思路:这个问题,理论上要确定那些数没有出现是要历遍的,问题是没有出现的数最少9千万过以上,所以太不划算的,所以我们要解决的是

          怎么保存这个不出现的数,而且可以省略去枚举这些不出现的数。

          下面我想到一种很省空间的标识方法,至于效率就不做深究了。

          首先,定义 一个结构体  struct tagArea{ long start, long end };

          然后对这1千万个随机数进行从小到大排序,之后从1开始 到排序后的数组比较  如果 当前数组比前一个数组大1以上 则保存到结构体

           即start赋予前一个数组的数 后面数组的数赋给 end  , 那么 没有出现的数就可以表示为(start,end)之间。

          类似 的 生成了 n个tagArea结构体,他们记录了 没有出项的数。

          另外一种方法是 用 二进制的每一bit表示那个数没有出现。 

代码转自 http://m.blog.csdn.net/blog/zhiyuan_2007/7642617

#include 
#include 
#include 
#include 

typedef unsigned char byte_t;
const int MAX = 100000;

void gen_rand(int num, int *arr)
{
    int i;
    unsigned long int ran;
    srand(time(NULL));
    for (i = 0; i < num; i++)
    {
        ran = rand() % MAX;
        arr[i] = ran;
     }
}

void noexist_bitset(int a[], int num)
{
    printf("bitset method result:\n");
    byte_t bitarray[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
    int mem_count = num / 8 + 1;
    unsigned char *bitset = (unsigned char *)malloc(sizeof(char) * mem_count);
    memset(bitset, 0, sizeof(char) * mem_count);
    int i = 0;
    int last_servel =  num % 8;
    unsigned char *cur_ptr = bitset + num / 8;
    for (; i < 8 - last_servel; i++) //set 1 for last several need't bit 
    {
        *cur_ptr |= bitarray[8 - i - 1];
    }
    i = 0;
    int cur_pos;
    int offset;
    for (; i < num; i++)
    {
        cur_pos = a[i] / 8;
        offset = a[i] % 8;
        cur_ptr = bitset + cur_pos;
        *cur_ptr = *cur_ptr | bitarray[offset];
    }

    i = 0;
    for (; i < mem_count; i++)
    {
        cur_ptr = bitset + i;
        int j = 0;
        for (; j < 8; j++)
        {
            unsigned char temp = *cur_ptr;
            int cmp_value = temp & bitarray[j];

            if (cmp_value == 0)
                printf("%d\t", i * 8 + j);
        }
    }
    free(bitset);
    printf("\n");
}

int main(int argc, char *argv[])
{
    int a[MAX];
   
    gen_rand(MAX, a);
   
    noexist_bitset(a, MAX);

	system("pause");
}


你可能感兴趣的:(10.百度最新面试题:现在有1千万个随机数,随机数的范围在1到1亿之间。现在要求写出一种算法,将1到1亿之间没有在随机数中的数求出来。)