欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java深入分析與解決Top-K問題

 更新時間:2022年04月26日 11:38:02   作者:淡沫初夏Zz  
TopK問題即在N個數(shù)中找出最大的前K個,這篇文章將詳細(xì)講解三種方法解決TopK問題,文中代碼具有一定參考價值,快跟隨小編一起學(xué)習(xí)一下吧

題目

求最小的K個數(shù)

設(shè)計一個算法,找出數(shù)組中最小的k個數(shù)。以任意順序返回這k個數(shù)均可。

解題方案

方法一

排序(冒泡/選擇)

思路

1,冒泡排序是每執(zhí)行一次,就會確定最終位置,執(zhí)行K次后,就可以得到結(jié)果,時間復(fù)雜度為O(n * k),當(dāng)k<<n時,O(n * k)的性能會比O(N*logN)好。

2,選擇排序每執(zhí)行依次,就會通過確定一個最大的或最小的放在一端,通過選擇排序,執(zhí)行K次就可以得到最大的K個數(shù)了。時間復(fù)雜度時O(N * K)。

代碼實現(xiàn)

  //冒泡排序
    public static int[] topKByBubble(int[] arr, int k) {
        int[] ret = new int[k];
        if (k == 0 || arr.length == 0) {
            return ret;
        }
        for (int i = 0; i < k; i++) {
            for (int j = arr.length - 1; j < i; j--) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
            ret[i] = arr[i];
        }
        return ret;
    }
    //選擇排序
    public static int[] topKBySelect(int[] arr, int k) {
        int[] ret = new int[k];
        for (int i = 0; i < k; i++) {
            int maxIndex = i;
            int maxNum = arr[maxIndex];
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] > maxNum) {
                    maxIndex = j;
                    maxNum = arr[j];
                }
            }
            if (maxIndex != i) {
                swap(arr, maxIndex, i);
            }
            ret[i] = arr[i];
        }
        return ret;
    }
    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

方法二

分治-快速排序

思路

1,快速排序的核心是分治思想,先通過分治partition把序列分為兩個部分,再將兩個部分進(jìn)行再次遞歸;

2,利用分治思想,即劃分操作partition,根據(jù)主元素pivot調(diào)整序列,比pivot大的放在左端,比pivot小的放在右端,這樣確定主元素pivot的位置pivotIndex,如果pivotIndex剛好是k-1,那么前k-1位置的數(shù)就是前k大的元素,即我們要求的top K。

時間復(fù)雜度: O(n)

代碼實現(xiàn)

public static int[] topKByPartition(int[] arr, int k){
    if(arr.length == 0 || k <= 0){
        return new int[0];
    }
    return quickSort(arr,0,arr.length-1,k);

}
//快速排序
public static int[] quickSort(int[] arr, int low, int high, int k){
    int n = arr.length;
    int pivotIndex = partition(arr, low, high);
    if(pivotIndex == k-1){
        return Arrays.copyOfRange(arr,0,k);
    }else if(pivotIndex > k-1){
        return quickSort(arr,low,pivotIndex-1,k);
    }else {
        return quickSort(arr,pivotIndex+1,high,k);
    }
}
public static int partition(int[] arr, int low, int high){
   if(high - low == 0){
       return low;
   }
   int pivot = arr[high];
   int left = low;
   int right = high-1;
   while (left < right){
       while (left < right && arr[left] > pivot){
           left++;
       }
       while (left < right && arr[right] < pivot){
           right--;
       }
       if(left < right){
           swap(arr,left,right);
       }else {
           break;
       }
   }
   swap(arr,high,left);
   return left;
}
public static void swap(int[] arr,int a, int b){
    int temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
}

方法三

利用堆

思路

1,構(gòu)建一個最大堆

2,遍歷原數(shù)組,元素入隊,當(dāng)堆的大小為K時,只需要將堆頂元素于下一個元素比較,如果大于堆頂元素,則將堆頂元素刪除,將該元素插入堆中,直到遍歷完所有元素

3,將queue存儲的K個數(shù)出隊

時間復(fù)雜度:為O(N*logK)

代碼實現(xiàn)

public class TopK {
    public int[] smallestK(int[] arr, int k) {
        int[] ret = new int[k];
        if(k==0 || arr.length==0){
            return ret;
        }
        // 1,構(gòu)建一個最大堆
        // JDK的優(yōu)先級隊列是最小堆, 就要用到我們比較器
        Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        //2,遍歷原數(shù)組,進(jìn)行入隊
        for(int value:arr){
            if(queue.size() < k){
                queue.offer(value);
            }else{
                if(value < queue.peek()){
                    queue.poll();
                    queue.offer(value);
                }
            }
        }
        //3,將queue中存儲的K個元素出隊
        for(int i = 0;i < k;i++){
            ret[i] = queue.poll();
        }
        return ret;
    }
}

到此這篇關(guān)于Java深入分析與解決Top-K問題的文章就介紹到這了,更多相關(guān)Java Top-K內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • Java中Buffer緩沖區(qū)的ByteBuffer類詳解

    Java中Buffer緩沖區(qū)的ByteBuffer類詳解

    這篇文章主要介紹了Java中Buffer緩沖區(qū)的ByteBuffer類詳解,ByteBuffer類是Java NIO庫中的一個重要類,用于處理字節(jié)數(shù)據(jù),它提供了一種靈活的方式來讀取、寫入和操作字節(jié)數(shù)據(jù),ByteBuffer類是一個抽象類,可以通過靜態(tài)方法創(chuàng)建不同類型的ByteBuffer對象,需要的朋友可以參考下
    2023-10-10
  • 如何安裝java的運行環(huán)境IDEA

    如何安裝java的運行環(huán)境IDEA

    這篇文章主要介紹了如何安裝java的運行環(huán)境IDEA,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java如何將Excel數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫

    Java如何將Excel數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了Java將Excel數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 淺談Spring Boot 異常處理篇

    淺談Spring Boot 異常處理篇

    本篇文章主要介紹了淺談Spring Boot 異常處理篇,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 關(guān)于File與MultipartFile的用法概述

    關(guān)于File與MultipartFile的用法概述

    這篇文章主要介紹了關(guān)于File與MultipartFile的用法概述,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java框架入門之簡單介紹SpringBoot框架

    Java框架入門之簡單介紹SpringBoot框架

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著SpringBoot框架展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 關(guān)于Java中的繼承和組合的一個錯誤使用的例子

    關(guān)于Java中的繼承和組合的一個錯誤使用的例子

    這篇文章主要介紹了關(guān)于Java中的繼承和組合的一個錯誤使用的例子,需要的朋友可以參考下
    2016-08-08
  • Java數(shù)據(jù)結(jié)構(gòu)之棧的詳解

    Java數(shù)據(jù)結(jié)構(gòu)之棧的詳解

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之棧簡單操作的相關(guān)資料,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • Eclipse 安裝 SVN 在線插件教程

    Eclipse 安裝 SVN 在線插件教程

    這篇文章主要介紹了Eclipse 安裝 SVN 在線插件教程的相關(guān)資料,這里對安裝步驟進(jìn)行了詳細(xì)介紹,需要的朋友可以參考下
    2016-11-11
  • Java設(shè)計模式之單態(tài)模式(Singleton模式)介紹

    Java設(shè)計模式之單態(tài)模式(Singleton模式)介紹

    這篇文章主要介紹了Java設(shè)計模式之單態(tài)模式(Singleton模式)介紹,本文講解了如何使用單例模式、使用單例模式注意事項等內(nèi)容,需要的朋友可以參考下
    2015-03-03

最新評論