/**
* 从n个不重复的整数中随机找出m个不重复的整数,要求时间和空间复复杂度都是O(m);
* 方法一: 随机产生n个不重复的随机数放在一个数组中,然后以数组的下标为界生成一个随机数,然后根据这个随机数(下标地址)获取数值,然后跟前面取到的数值作比较,如果重复,就重新生产,直到取到n个不重复的数为止;
* 方法二: 在方法一的基础上,每次将产生的随机数(下标)对应的值和数组的最后一个值做交换,下一次在数组的最后一个值之前产生随机坐标(依次类推),这样避免了每次生产的随机数在数组中做比较;
* 方法一: 2208300
* 方法二: 149900
*/
public class FindNumber {
public static void main(String[] args) {
int n = 100;
int m = 99;
int [] parents = new int[100];
for (int i=0; i<n; i++) {
parents[i] = i+1;
}
long startTime = System.nanoTime();
int [] children = method2(parents, m);
System.out.println(System.nanoTime() - startTime);
for (int i=0; i<children.length; i++) {
System.out.println(children[i]);
}
}
public static int[] method2(int [] parents, int m) {
int[] children = new int[m];
int length = parents.length;
if (length <= m) {
return parents;
}
for (int i=0; i<m; i++) {
int len = length - i;
int random = (int) (Math.random() * len);
int number = parents[random];
children[i] = number;
parents[random] = parents[random] ^ parents[len-1];
parents[len-1] = parents[random] ^ parents[len-1];
parents[random] = parents[random] ^ parents[len-1];
}
return children;
}
public static int[] method1(int [] parents, int m) {
int[] children = new int[m];
int length = parents.length;
if (length <= m) {
return parents;
}
while (true) {
int random = (int) (Math.random() * length);
int number = parents[random];
for (int i=0; i<m; i++) {
if (children[i] == 0) {
children[i] = number;
break;
} else if (children[i] == number) {
break;
}
}
if (children[m-1] != 0) {
break;
}
}
return children;
}
}