在 nlog(n) 时间内实现递归 shuffle 数组方法的问题

问题描述

我正在尝试实现一个需要 nlog(n) 时间的递归 shuffle 方法,但是我遇到了很大的困难,因为我被限制为一个参数并且在调用时不能在我的参数中包含 n 的大小递归方法。我查看了具有不同参数的类似改组问题的结构,并获得了如何使用 Random 来构建改组的想法,但我花了太多时间试图弄清楚如何实现这一点。

如果我可以实现带有两个参数 a 和 n 的方法,我觉得我不会有这么多麻烦。我的问题是,为了递减它,我应该让 n 成为一个全局变量吗?我将如何减少 n 以管理递归,或者以某种方式修改 a 以最终结束递归?

*此外,像这样在索引中声明对象会导致引用问题吗?如果是这样,我将如何解决这个问题?我尝试了克隆,但无法使其在问题要求范围内发挥作用。

    public static void shuffle(Object[] a) {
        int n = a.length;
        if (n == 0) {
            return;
         }
         int d = (int) (Math.random() * (n-1));  //random index
         Object c = a[n - 1];  //value at n-1
         a[n-1]= a[d]; //a[n-1] index = val at rand index
         a[d] =  c;         //val at rand index set to val at n-1
         shuffle(a);
        
        
        
        shuffle(a);
    }

***我开始实施的看起来更像是在 nlogn 时间复杂度下工作,但不确定它是否正确或需要如何完成...

public static void shuffle(Object[] a){
   if(a.length == 1) return;  //return if length = 1: base case 

    Object[] b = new Object[a.length/2]();
    Random rand = new Random(0,a.length); //random index to swap


   for(int i = 0; i < b.length; i++){
       b[i] = a[rand];                 //how do I make sure no index of a is 
                    //repeated? 
  }

   shuffle(b); //recursively call shuffle on b,dividing size by 2

   for(int i = 0; i < a.length; i++){
       a[i] = b[i];  //copy values from b to a (I guess you Could use arraycopy)
   }

   }

解决方法

如果我可以实现带有两个参数 a 和 n 的方法,我觉得我不会有这么多麻烦。我的问题是,为了递减它,我应该让 n 成为一个全局变量吗?

它不必是全局变量。您可以在您的方法中创建一个类,如下所示。这应该支持实现必须保留在公开可用的方法中的任何要求。当然,您需要确定这是否符合您的问题中未提及的任何其他限制。我把实际的算法留给你。但是数组可以在 O(n) 中就地打乱。

public static void shuffle(Object[] a) {
    class Shuffle {
        private void recShuffle(Object[] ob,int n) {
            // your shuffle algorithm here
        }
    }
    Shuffle s = new Shuffle();
    int n = ... // up to you
    s.recShuffle(a,n);
}
,

所以我今天早上找到了一种解决方法,方法是实现一个辅助方法并将我的大部分代码移到那里,以防有人遇到这样的问题:

    //calls helper shuffle method
     public static void shuffle(Object[] a) {
        int n = a.length;
         helperShuffle(a,n);
        
    }
    
    public static Object[] helperShuffle(Object[] a,int n) {
        if (n <= 1) 
            return a; //base case: size of array is 1 
        
        Random rand = new Random(); //declare new random
        int d = (rand.nextInt(n));  //random index < n 
        Object c = a[n - 1];  //value at n-1
        a[n-1]= a[d]; //a[n-1] index = val at rand index
        a[d] =  c;         //val at rand index set to val at n-1
        
        return helperShuffle(a,n-1); 
    }