TopK (MinK) 实现

Posted dqwangi33

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TopK (MinK) 实现相关的知识,希望对你有一定的参考价值。

概述:基于快排原理找到最小的K个元素,属于Top K问题。注意,使用快排原理找前K小问题不需要对整个数组进行O(nlogn)的排序。我们只要找K所在的区间进行递归调用,即每次只要对数据的一半进行递归调用,而不用对全部的数据进行递归调用,从而降低了时间复杂度。平均情况下,时间复杂度计算:n + n/2 +  ... + n/n = 2n, 因此时间复杂度是O(n)。

 1 import java.util.Arrays;
 2 public class MinK {
 3     public static void main(String[] args) {
 4         int[] arr = {3,45,78,64,52,64,64,55,55,11,2};
 5         System.out.println(arrayToString(arr,"Array:"));
 6         int k = 3;
 7         int[] res = quickSearch(arr, 0, arr.length-1, k);
 8         System.out.println(arrayToString(res,"MinK :"));    
 9     }
10     /**
11      * 基于快排找到最小的K个元素
12      * nums   数组
13      * left  数组左下标
14      * right 数组右下标
15      * k     k值
16      */
17 
18     
19     private static int[] quickSearch(int[] nums, int left, int right, int k) {
20         // 每快排切分1次,找到排序后下标为j的元素,如果j恰好等于k就返回j以及j左边所有的数;
21         int j = partition(nums, left, right);
22         if (j == k) {
23             return Arrays.copyOf(nums, j);
24         }
25         else if (j < k) {
26             return quickSearch(nums,j+1, right, k);
27         } 
28         else{
29             return quickSearch(nums, left, j-1, k);
30         }
31     }
32 
33     // 快排切分,返回下标j,使得比numss[j]小的数都在j的左边,比numss[j]大的数都在j的右边。
34     private static int partition(int[] nums, int left, int right) {
35         int key = nums[left];
36         int i = left;
37         int j = right;
38         while(i<j){   //当i=j时退出总循环
39             while(nums[j] >= key && i < j) j--;  //从右往左,找到比key小的值方可退出循环
40             while(nums[i] <= key && i < j) i++;  //从左往右,找到比key大的值方可退出循环
41             if(i<j){
42                 int temp = nums[i];  // 把左边大的值与右边小的值进行交换
43                 nums[i] = nums[j];
44                 nums[j] = temp;    
45             }
46         }
47         nums[left] = nums[i];
48         nums[i] = key;   //把key交换到中间
49         return i;
50     }
51     private static String arrayToString(int[] arr,String flag) {
52         String str = flag+‘	‘;
53         for(int a : arr) {
54             str += a + "	";
55         }
56         return str;
57     }
58 
59 }

结果:

技术图片

 

以上是关于TopK (MinK) 实现的主要内容,如果未能解决你的问题,请参考以下文章

数据结构TopK问题

如何有效地测试使用 Behat/Mink 访问大文件?

找出数组中第k大的数(时间复杂度分析C++代码实现). TopK in array. ( leetcode - 215 )

找出数组中第k大的数(时间复杂度分析C++代码实现). TopK in array. ( leetcode - 215 )

数据结构 设计一个算法,删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数,其值 可以和表中的元素相同,也可以不同)

如何使用 Behat/Mink 切换到动态命名的 iframe