经典算法题随机从连续的100个不重复数中取出100个不重复随机数

经典的面试题:  产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复

网上实现的方法也千奇百怪.

实现思路:

(1)把N个数放入Hashtable 或者arrayList 中.

(2)从上面的集合中随机抽取一个数放入int数组中.

(3)把取出的这个数从上面的集合中删除.

(4)循环 (2),(3) 步骤,直到int数组取满为止.

我们一般都会想到这种做法,但是当Hashtable或者ArrayList中放几千万,几亿数据时,这时从集合中删除元素将严重影响性能,如果突破此瓶颈? 网上找到一种更好的方法.

(1)把N个数放到容器A(int数组)中.

(2)从N个数中随机取出1个数放入容器B(int数组)中.

(3)把容器A中最后一个数与随机抽取的数对调 或者 把容器A中最后一个数覆盖随机抽取出来的数.

(4)这时从容器A(假设N个数,索引0 到 索引N-2)之间随机取一个数.再放入容器B中,重复此步骤.

说明:也就是第二次是从容器A中 第一个元素到倒数第二个元素 中随机取一个数.

这种好处是,随机数所取范围逐步缩小,而且杜绝了大数据时集合执行删除操作时产生的瓶颈.

下面给出DEMO(这里的是将容器B中最后一个数覆盖所取的随机数)

 

public static int[] GetNumber(int total)

{

  int[] NumberBox = new int[total];//容器A

  int[] rtnNumber = new int[total];//容器B



for (int i = 0; i < total; i++)

{

  NumberBox[i] = i;//先把N个数放入容器A中

}

Random rad = new Random();

int end = total - 1;

for (int j = 0; j < total; j++)

{

  int num = rad.Next(0, end + 1);//取随机数

  rtnNumber[j] = NumberBox[num];//把随机数放入容器B

  NumberBox[num] = NumberBox[end];//把容器A中最后一个数覆盖所取的随机数

  end--;//缩小随机数所取范围

}



  return rtnNumber;//返回int型数组

}

 

你可能感兴趣的:(随机数)