1. 程式人生 > >Top k問題的討論(三種java實現)

Top k問題的討論(三種java實現)

在很多的筆試和麵試中,喜歡考察Top K.下面從自身的經驗給出三種實現方式及實用範圍。

合併法

這種方法適用於幾個陣列有序的情況,來求Top k。時間複雜度為O(k*m)。(m:為陣列的個數).具體實現如下:

/**
* 已知幾個遞減有序的m個數組,求這幾個資料前k大的數
*適合採用Merge的方法,時間複雜度(O(k*m);
*/
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
public class TopKByMerge{
 public int[] getTopK(List<List<Integer>>input,int
k){ int index[]=new int[input.size()];//儲存每個陣列下標掃描的位置; int result[]=new int[k]; for(int i=0;i<k;i++){ int max=Integer.MIN_VALUE; int maxIndex=0; for(int j=0;j<input.size();j++){ if(index[j]<input.get(j).size()){ if(max<input.get(j).get(index[j])){ max=input.get(j).get(index[j]); maxIndex=j; } } } if
(max==Integer.MIN_VALUE){ return result; } result[i]=max; index[maxIndex]+=1; } return result; }

快排過程法

快排過程法利用快速排序的過程來求Top k.平均時間複雜度為(O(k*logn).適用於無序單個數組。具體Java實現如下:

/*
*利用快速排序的過程來求最小的k個數
*
*/
public class TopK{
  int partion(int a[],int first,int end){
      int i=first;
      int
main=a[end]; for(int j=first;j<end;j++){ if(a[j]<main){ int temp=a[j]; a[j]=a[i]; a[i]=temp; i++; } } a[end]=a[i]; a[i]=main; return i; } void getTopKMinBySort(int a[],int first,int end,int k){ if(first<end){ int partionIndex=partion(a,first,end); if(partionIndex==k-1)return; else if(partionIndex>k-1)getTopKMinBySort(a,first,partionIndex-1,k); else getTopKMinBySort(a,partionIndex+1,end,k); } } public static void main(String []args){ int a[]={2,20,3,7,9,1,17,18,0,4}; int k=6; new TopK().getTopKMinBySort(a,0,a.length-1,k); for(int i=0;i<k;i++){ System.out.print(a[i]+" "); } } }

採用小根堆或者大根堆

求最大K個採用小根堆,而求最小K個採用大根堆。

求最大K個的步奏:

1、根據資料前K個建立K個節點的小根堆。
2、在後面的N-K的資料的掃描中,
  如果資料大於小根堆的根節點,則根節點的值覆為該資料,並調節節點至小根堆。
  如果資料小於或等於小根堆的根節點,小根堆無變化。

求最小K個跟這求最大K個類似。時間複雜度O(nlogK)(n:資料的長度),特別適用於大資料的求Top K。

/**
 * 求前面的最大K個 解決方案:小根堆 (資料量比較大(特別是大到記憶體不可以容納)時,偏向於採用堆)
 * 
 * 
 */
public class TopK {
  /**
   * 建立k個節點的小根堆
   * 
   * @param a
   * @param k
   * @return
   */
  int[] createHeap(int a[], int k) {
    int[] result = new int[k];
    for (int i = 0; i < k; i++) {
      result[i] = a[i];
    }
    for (int i = 1; i < k; i++) {
      int child = i;
      int parent = (i - 1) / 2;
      int temp = a[i];
      while (parent >= 0 &&child!=0&& result[parent] >temp) {
        result[child] = result[parent];
        child = parent;
        parent = (parent - 1) / 2;
      }
      result[child] = temp;
    }
    return result;

  }

  void insert(int a[], int value) {
     a[0]=value;
     int parent=0;

     while(parent<a.length){
       int lchild=2*parent+1;
       int rchild=2*parent+2;
       int minIndex=parent;
       if(lchild<a.length&&a[parent]>a[lchild]){
         minIndex=lchild;
       }
       if(rchild<a.length&&a[minIndex]>a[rchild]){
         minIndex=rchild;
       }
       if(minIndex==parent){
         break;
       }else{
         int temp=a[parent];
         a[parent]=a[minIndex];
         a[minIndex]=temp;
         parent=minIndex;
       }
     }

  }

  int[] getTopKByHeap(int input[], int k) {
    int heap[] = this.createHeap(input, k);
    for(int i=k;i<input.length;i++){
      if(input[i]>heap[0]){
        this.insert(heap, input[i]);
      }


    }
    return heap;

  }

  public static void main(String[] args) {
    int a[] = { 4, 3, 5, 1, 2,8,9,10};
    int result[] = new TopK().getTopKByHeap(a, 3);
    for (int temp : result) {
      System.out.println(temp);
    }
  }
}

相關推薦

Top k問題的討論java實現

在很多的筆試和麵試中,喜歡考察Top K.下面從自身的經驗給出三種實現方式及實用範圍。 合併法 這種方法適用於幾個陣列有序的情況,來求Top k。時間複雜度為O(k*m)。(m:為陣列的個數).具體實現如下: /** * 已知幾個遞減有序的m個數組

刪除鏈表的倒數第N個節點方法實現

from ++ n+1 while end != bsp -- 結點 刪除鏈表的倒數第N個節點 給定一個鏈表,刪除鏈表的倒數第 n 個節點,並且返回鏈表的頭結點。 示例: 給定一個鏈表: 1->2->3->4->5, 和 n = 2. 當刪

最短路和差分約束演算法實現 Til the Cows Come Home

題目訓練連結(密碼hpuacm): https://vjudge.net/contest/246705 我會分別用 迪傑斯特拉  優先佇列和鏈式前向星優化過的迪傑斯特拉  SPFA演算法 三種方法講一下例題。 此外上述三種演算法是求單源最短路問題, 這裡還會

url地址資料引數轉化JSON物件js方法實現

當我們用get方法提交表單時,在url上會顯示出請求的引數組成的字串,例如:http://localhost:3000/index.html?phone=12345678901&pwd=123123,在伺服器端我們要獲取其中的引數來進行操作,這種情況下,就要對請求過來的網址進行拆解了。下面將用3種方法

【轉】Mybatis傳多個參數解決方案

三種 方案 var nbsp myba rom name bsp 什麽 轉自: http://www.2cto.com/database/201409/338155.html 據我目前接觸到的傳多個參數的方案有三種。 第一種方案: DAO層的函數方法 Public

數據結構-冒泡排序Python&java實現

冒泡排序1. 冒泡算法的核心思想冒泡排序的核心思想就是掃描數據清單,找到亂序的兩個相鄰的數據進行兩兩比較並交換位置,然後繼續掃描數據,接著反復重復上述的操作直至排序結束。2. 示例我們以23,15,58,-4,99,0這組無序的數字為例:例子為從小到大排序,初始狀態:23,15,58, -4,99

數據結構-插入排序Python&java實現

數據結構 java python 插入排序1.插入排序的工作原理插入排序的工作原理是通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。2.示例我們以3,0,89,67,-2,9這組無序的數字為例:例子為從小到大排序,初始狀態 3 0 89 67 -2 9

修改陣列中的變數,無法立馬觸發檢視更新解決方案

第一:使用$set. 直接給student賦值操作,雖然可以新增屬性,但是不會觸發檢視更新 mounted () { this.student.age = 24}原因是:受 ES5 的限制,Vue.js 不能檢測到物件屬性的新增或刪除。因為 Vue.js 在初始化例項時將屬性轉為 getter/sette

使用結巴分詞jieba對自然語言進行特徵預處理Python、Java 實現

一、前言 之前使用基於 Python 語言的 Spark 進行機器學習,程式設計起來是十分簡單。 ① 但是演算法部署到雲伺服器上,是一個障礙。 ② 得藉助 Flask/Django 等 Python W

Winform遍歷視窗的所有控制元件方式實現

C#遍歷窗體所有控制元件或某型別所有控制元件 //遍歷窗體所有控制元件, foreach (Control control in this.Controls) { //遍歷後的操作... control.Enabled = false; } 遍歷某個panel的所有控制元件

js對url進行編碼和解碼方式區別

*** 只有 0-9[a-Z] $ - _ . + ! * ' ( ) , 以及某些保留字,才能不經過編碼直接用於 URL。 ***例如:搜尋的中文關鍵字,複製網址之後再貼上就會發現該URL已經被轉碼。 1、escape 和 unescape 原理:對除ASCII字母、數字、標點符號 @  *  _  +

2.二維陣列中的查詢python和java實現

題目:在一個二維陣列中,每一行都是按照從左到右遞增的順序排序,每一列都是安裝從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中書否含有該整數。 演算法思想:我們知道每一行都是遞增排序的,每一列也是從上到下遞增排序的,所以左上角的數是最小的,

python 實現 列表 選擇排序 演算法方法實現

方法一:(remove方法) arr = [2, 3, 5, 6, 4, 1, 9] #找出最小元素 def findsmallest(arr): smallest = arr[0] #假設第一個元素為最小值 for i in range(1,len(arr)):

Mybatis傳多個參數解決方案 mapper.xml的sql語句修改!

修改 and 接收 select sql 函數 resultmap rom var 第一種 Public User selectUser(String name,String area); 對應的Mapper.xml <select id="selectUs

單鏈表反轉方法總結

題目:輸入一個連結串列,反轉連結串列後,輸出連結串列的所有元素。 方法一: 思路:從原連結串列的頭部一個一個取節點並插入到新連結串列的頭部 (1) struct ListNode{ int val; struct ListNode *nex

二叉樹非遞迴遍歷+層序

#include <iostream> #include <stdio.h> #include <queue> #include <stack> using namespace std; typedef struct BiTN

MQTT+ActiveMQ實現訊息推送伺服器端java實現

上一篇文章已經介紹了mqtt+activemq實現訊息推送移動端的實現,也介紹了利用自帶的web console進行訊息釋出的方法。但是在具體的專案應用中,當我們將需要將該訊息推送模組嵌入到一個後臺管理系統當中,我們就需要在web端來訪問activeMQ來進行訊

設計模式與應用:代理模式詳解

簡介 Proxy代理模式,是構造型的設計模式之一 代理模式為其他物件提供代理以控制這個物件的訪問。 所謂代理,是指具有與代理元(被代理物件)具有相同介面的類。client需要通過代理與被代理的目標類互動,代理類就是在互動的過程中(前後

ajax跨域問題解決方案

為什麼會出現跨域 跨域問題來源於JavaScript的同源策略,即只有 協議+主機名+埠號 (如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其

Selenium練習四:百度搜索自動化指令碼定位方式

1. 實現百度搜索的自動化測試指令碼,需滿足要求如下: 1)瀏覽器至少選擇兩種(火狐+chrome/ie),關鍵詞為“福哥雜記 CSDN”; 2)指令碼檔案命名為“{組名}_{姓名}_百度搜索_{瀏覽器}_{指令碼序號}.py” 3)搜尋框和“百度一下”元素的定位方式,至少