【问题标题】:Kth minimum element using quickselect with random pivot使用带有随机枢轴的快速选择的第 K 个最小元素
【发布时间】:2021-03-14 15:53:00
【问题描述】:

我正在尝试使用快速选择算法在数组中找到第 k 个最小的。但是,当我尝试随机选择枢轴时,输出也是随机的。

以下是我的方法实现,

    static int findKthMin(int[]arr, int n, int k) {
        int l=0 , r=n-1;
        Random random = new Random();
        while(true) {
            int x = random.nextInt(r+1-l) + l; // When using x = r (works correctly)
            int pivot = arr[x];
            int idx = l;
            for(int i=l;i<=r;i++) {
                if(arr[i] < pivot) {
                    int temp = arr[idx];
                    arr[idx] = arr[i];
                    arr[i] = temp;
                    
                    idx++;
                }
            }
            arr[x] = arr[idx];
            arr[idx] = pivot;
            
            if(idx == k-1) return pivot;
            
            if(idx > k-1) {
                r = idx-1;
            } else {
                l = idx;
            }
        }
    }

这里,n 是数组的大小,k 是要找到的第 k 个最小元素。
当我使用x=r 时,代码运行良好。

我的猜测是条件有问题

   for(int i=l;i<=r;i++) {
       if(arr[i] < pivot) {
            int temp = arr[idx];
            arr[idx] = arr[i];
            arr[i] = temp;

            idx++;
       }
   }          

但我不知道出了什么问题以及如何解决它。我花了几个小时调试它并更改代码,但可以找出问题所在。

这是我正在尝试的测试用例,

6               // n
7 10 4 3 20 15  //arr
3               // k

还有,

5             // n
7 10 4 20 15  // arr
4             // k

通过这些测试用例,随机枢轴将任何数组元素作为输出。
任何可能是错误的提示都会非常有帮助。

【问题讨论】:

  • 我假设你是从维基百科页面改编的?您忘记了在进行任何交换之前将枢轴元素移到后面的步骤。此外,这个循环应该一直运行到i &lt; r
  • @NicoSchertler 谢谢你的建议。即使我没有提到任何 Wiki 实现,我也很愚蠢,因为我没有考虑将随机枢轴元素交换到最后一个元素。之后就可以正常使用了。

标签: java algorithm quicksort


【解决方案1】:

根据@Nico 的建议,我只需要将枢轴元素与最后一个交换即可。
以下是完整的工作 sn-p,

    static int findKthMin(int[]arr, int n, int k) {
        int l=0 , r=n-1;
        Random random = new Random();
        while(true) {
            int x = random.nextInt(r+1-l) + l; // When using x = r (works correctly)

            //Swap random pivot with the last index element
            int temp = arr[x];
            arr[x] = arr[r];
            arr[r] = temp;

            int pivot = arr[r];

            int idx = l;
            for(int i=l;i<=r;i++) {
                if(arr[i] < pivot) {
                    temp = arr[idx];
                    arr[idx] = arr[i];
                    arr[i] = temp;

                    idx++;
                }
            }
            arr[r] = arr[idx];
            arr[idx] = pivot;

            if(idx == k-1) return pivot;

            if(idx > k-1) {
                r = idx-1;
            } else {
                l = idx;
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2018-09-21
    • 1970-01-01
    • 2017-06-23
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多