去面试时有一个小算法题。感觉呢?还好吧,记录一下。问题,给一个数组,实现打乱数组的循序。如array={1,2,3,4,5,6,7,8,9,10,11,12,13……45},一个随机函数Random(45);
思考:就是随机生成45个不重复的随机数数组。代码如下
//防止重复
TreeSet<Integer> treeSet = new TreeSet<>();
for (int i = 0; i < array.length; i++) {
int number = -1;
number = getRandomNumber(array.length);
if (treeSet.add(number)) {
array[i] = number;
} else {//重复了进行重新生成随机数
do {
number = getRandomNumber(array.length);
} while (!treeSet.add(number));
array[i] = number;
}
}
for (int v : array) {
System.out.print(v + ", ");
}
但是看到这个代码,感觉味道非常不好。感觉重复了。其实就是当没有重复的时候进行添加。于是改为如下:
//防止重复
TreeSet<Integer> treeSet = new TreeSet<>();
for (int i = 0; i < array.length; i++) {
int number = -1;
// number = getRandomNumber(array.length);
// if (treeSet.add(number)) {
// array[i] = number;
// } else {//重复了进行重新生成随机数
do {
number = getRandomNumber(array.length);
} while (!treeSet.add(number));
array[i] = number;
// }
}
for (int v : array) {
System.out.print(v + ", ");
}
再度思考。其实,这个随机函数Random会不断调用。而且已经超过了数组的size的次数。如果出现糟糕的情况,不断生成同一个随机(一种可能),那么这个算法就是危险的了。所以推倒重来。采用换位的思想:如果随机到一个操作下标。就进行换位。代码如下
for (int i = 0; i < array.length; i++) {
Random random = new Random();
//随机下标
int index = random.nextInt(array.length);
int move = array[i];
array[i] = array[index];
array[index] = move;
}
for (int v : array) {
System.out.print(v + ", ");
}
这样就简单多了。随机了size的数。而且达到了目的。