TopK算法

TopK算法看前三种。

基于快排的TopK算法:

快速排序使用了分治法的策略。它的基本思想是,选择一个基准数(一般称之为枢纽元),通过一趟排序将要排序的数据分割成独立的两部分:在枢纽元左边的所有元素都不比它大,右边所有元素都比它大,此时枢纽元就处在它应该在的正确位置上了。

在本问题中,假设有N个数存储在数组a中。我们从a中随机找出一个元素作为枢纽元,把数组分为两部分。其中左边元素都不比枢纽元大,右边元素都不比枢纽元小。此时枢纽元所在的位置记为mid。

如果右半边(包括a[mid])的长度恰好为k,说明a[mid]就是需要的第k大元素,直接返回a[mid]。

如果右半边(包括a[mid])的长度大于k,说明要寻找的第k大元素就在右半边,往右半边寻找。

如果右半边(包括a[mid])的长度小于k,说明要寻找的第k大元素就在左半边,往左半边寻找。

package com.test;

public class QuickSort {
    public static void main(String[] args) {
        int nums[] = {1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9};
        int result = findMaxK(nums, 0, nums.length - 1, 3);
        System.out.println(result);
    }

    // TopK解法之快速排序
    public static int QuickSort(int[] nums, int low, int high) {
//        // 随机选一个元素作为枢纽元素
//        // 左边都是比枢纽元素小的,右边都是比枢纽元素大的
//        Random random = new Random();
//        // 生成指定范围为[low, high]的随机数
//        int idx = random.nextInt(high - low + 1) + low;
//        // 将枢纽元素换到low的位置,接下来的代码就和快排的代码一样了
        
        // 不取随机数了,就去low下标的元素
        int temp = nums[low];
        while (low < high) {
            while (low < high && nums[high] >= temp) high--;
            if (low < high) {
                nums[low++] = nums[high];
            }
            while (low < high && nums[low] < temp) low++;
            if (low < high) {
                nums[high--] = nums[low];
            }
        }
        nums[low] = temp;
        return low;
    }

    public static int findMaxK(int[] nums, int low, int high, int k) {
        int mid = QuickSort(nums, low, high);
        int length_of_right = high - mid + 1;
        if (length_of_right == k) return nums[mid];
        else if (length_of_right < k) {
            return findMaxK(nums, low, mid - 1, k);
        } else {
            return findMaxK(nums, mid + 1, high, k);
        }
    }
}

你可能感兴趣的:(面经)