• Top K Frequent Elements 之 topk问题


    topk问题是一个十分经典的问题,解决该问题主要有两种思路。

    第一种是利用 堆 结构,讲解:https://www.cnblogs.com/chengxiao/p/6129630.html

    第二种是利用 快速排序

    先回顾一下实现堆结构的代码:

    package LCtest.com;
    import java.util.Arrays;
    
    public class HeapSort {
        public static void main(String[] args) {
            int[] nums = {5, 8, 6};
            heapSort(nums);
            System.out.println(Arrays.toString(nums));
        }
        public static void heapSort(int[] nums){
            for(int i = nums.length/2-1; i >= 0; i--){
                adjustHeap(nums, i, nums.length);
            }
            for(int j = nums.length-1; j > 0; j--){
                swap(nums, 0, j);
                adjustHeap(nums, 0, j);
            }
        }
        public static void adjustHeap(int[] nums, int i, int length){
            int temp = nums[i];
            for(int k = 2*i+1; k < length; k = 2*k+1){
                if(k+1 < length && nums[k] < nums[k+1])
                    k++;
                if(nums[k] > temp){
                    nums[i] = nums[k];
                    i = k;
                }else {
                    break;
                }
            }
            nums[i] = temp;
        }
        public static void swap(int[] nums, int i, int j){
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }

    本题用了PriorityQueue实现了最小堆:

    class Solution {
        Map<Integer, Integer> count;
        public int[] topKFrequent(int[] nums, int k) {
            count = new HashMap<>();
            for(int num: nums){
                count.put(num, count.getOrDefault(num, 0)+1);
            }
            PriorityQueue<Integer> minheap = new PriorityQueue<>(new Comparator<Integer>(){
               @Override
                public int compare(Integer o1, Integer o2){
                    return count.get(o1)-count.get(o2);
                }
            });
            for(int num: count.keySet()){
                minheap.add(num);
                if(minheap.size() > k) minheap.remove();
            }
            int[] res = new int[k];
            for(int i = k-1; i >= 0; i--){
                res[i] = minheap.remove();
            }
            return res;
        }
    }

    回顾快速排序实现的代码:

    package LCtest.com;
    import java.util.Arrays;
    
    public class QuickSort {
        public static void main(String[] args){
            int[] nums = {5, 8, 6};
            quickSort(nums, 0, nums.length-1);
            System.out.println(Arrays.toString(nums));
        }
        public static void quickSort(int[] nums, int left, int right){
            if(left > right) return;
            int mid = partition(nums, left, right);
            quickSort(nums, left, mid-1);
            quickSort(nums, mid+1, right);
        }
        public static int partition(int[] nums, int low, int high){
            int temp = nums[low];
            while(low < high){
                while(low < high && nums[high] >= temp)
                    high--;
                nums[low] = nums[high];
                while (low < high && nums[low] <= temp)
                    low++;
                nums[high] = nums[low];
            }
            nums[low] = temp;
            return low;
        }
        public static void swap(int[] nums, int low, int high){
            int temp = nums[low];
            nums[low] = nums[high];
            nums[high] = temp;
        }
    }

    本题用快速排序求解的代码:

    class Solution {
        int[] unique;
        Map<Integer, Integer> count;
        public int[] topKFrequent(int[] nums, int k) {
            count = new HashMap<>();
            for(int num: nums){
                count.put(num, count.getOrDefault(num, 0)+1);
            }
            int n = count.size();
            unique = new int[n];
            int i = 0;
            for(int num: count.keySet()){
                unique[i] = num;
                i++;
            }
            sort(0, n-1, n-k);
            return Arrays.copyOfRange(unique, n-k, n);
        }
        public void sort(int left, int right, int loc){
            if(left > right) return;
            int mid = partition(left, right);
            if(mid == loc) return;
            else if(mid > loc){
                sort(left,mid-1, loc);
            }
            else{
                sort(mid+1, right, loc);
            }
        }
        public int partition(int low, int high){
            int pivot = count.get(unique[low]);
            int pu = unique[low];
            while(low < high){
                while(low < high && pivot <= count.get(unique[high]))
                    high--;
                unique[low] = unique[high];
                while(low < high && pivot >= count.get(unique[low]))
                    low++;
                unique[high] = unique[low];
            }
            unique[low] = pu;
            return low;
        }
    }
  • 相关阅读:
    python学习(一)
    Ubuntu安装git
    HashMap源码分析
    nginx加密,访问接口认证
    MD5加密加盐
    xml转对象,对象转xml工具类
    java将对象转map,map转对象工具类
    阿里备战--面试搜集
    java将秒转换为时分秒工具类
    Spring和SpringMvc详细讲解
  • 原文地址:https://www.cnblogs.com/yawenw/p/13019072.html
Copyright © 2020-2023  润新知