一个随机数组的算法问题

去面试时有一个小算法题。感觉呢?还好吧,记录一下。问题,给一个数组,实现打乱数组的循序。如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的数。而且达到了目的。


版权声明:本文为u012131702原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。