無序序列中O(n)時間複雜度尋找最小(最大)的K個數
一、快速排序,平均複雜度為n*logn
二、維護K個最小(最大)堆,平均複雜度為n*logK
三、類似快排的劃分方法
尋找N個數中最大的K個數,本質上就是尋找最大的K個數中最小的那個,也就是第K大的數。
可以使用二分搜尋的策略來尋找N個數中的第K大的數。對於一個給定的數p,可以在O(N)的時間複雜度內找出所有不小於p的數。
尋找第k大的元素:
#include <iostream> using namespace std; //快速排序的劃分函式 int partition(int a[],int l,int r) { int i,j,x,temp; i = l; j = r+1; x = a[l]; //將>=x的元素換到左邊區域 //將<=x的元素換到右邊區域 while (1) { while(a[++i] > x); while(a[--j] < x); if(i >= j) break; temp = a[i]; a[i] = a[j]; a[j] = temp; } a[l] = a[j]; a[j] = x; return j; } //隨機劃分函式<span style="color:#ff0000;">(注:也可以使用無分化中項的中項方法,或者中位數的中位數方法來劃分,不然無法達到O(n)的複雜度) </span>int random_partition(int a[],int l,int r) { int i = l+rand()%(r-l+1);//生產隨機數 int temp = a[i]; a[i] = a[l]; a[l] = temp; return partition(a,l,r);//呼叫劃分函式 } //線性尋找第k大的數 int random_select(int a[],int l,int r,int k) { int i,j; if (l == r) //遞迴結束 { return a[l]; } i = random_partition(a,l,r);//劃分 j = i-l+1; if(k == j) //遞迴結束,找到第K大的數 return a[i]; if(k < j) { return random_select(a,l,i-1,k);//遞迴呼叫,在前面部分查詢第K大的數 } else return random_select(a,i+1,r,k-j);//遞迴呼叫,在後面部分查詢第K大的數 } int main() { int a[]={1,2,3,4,6,6,7,8,10,10}; cout<<random_select(a,0,9,1)<<endl; cout<<random_select(a,0,9,5)<<endl; return 0; }
相關推薦
無序序列中O(n)時間複雜度尋找最小(最大)的K個數
一、快速排序,平均複雜度為n*logn 二、維護K個最小(最大)堆,平均複雜度為n*logK 三、類似快排的劃分方法 尋找N個數中最大的K個數,本質上就是尋找最大的K個數中最小的那個,也就是第K大的數。 可以使用二分搜尋的策略來尋找N個數中的第K大的數。對於一個給定的數p,
在柱狀圖中找最大矩形——O(n)時間複雜度java實現
最近在刷leetcode,又碰到了這道題,想起來當時演算法有些瑕疵,所以將最新的AC程式碼更新在最上面做個對比,具體思路見註釋. public class Solution { // 思路: 主要是使用一個棧來儲存陣列元素的下標,注意是儲存‘下標’。
在O(n)時間複雜度內找出陣列中的眾數
bool FindMostApperse(int *num,int len,int &candidate) { int count = 0; for(int i = 0;i < len;++i) { if(count == 0)
面試題:top k演算法O(n)時間複雜度
在《資料結構與演算法分析--c語言描述》一書,第7章第7.7.6節中,闡述了一種在平均情況下,時間複雜度為O(N)的快速選擇演算法。如下述文字: 選取S中一個元素作為樞紐元v,將集合S-{v}分割成S1和S2,就像快速排序那樣 如果k <= |S1|,那麼第k個最小
動態規劃演算法(連續子陣列最大和,O(N)時間複雜度O(1)空間複雜度) 【更新於:2018-05-13】
這個題目最早在13年阿里筆試出現,直到前兩天面試另一家電商又出現,哎,欠的都是要還的。 這個問題的思路如下:一維陣列的下標連續的元素構成連續子陣列,求所有連續子陣列中和最大的那個子陣列。 解析:2018-11-08 1 首先這個問題要轉化為Q(n)的問題,對於Q(n)的
強大的隨機演算法-簡潔的O(n)時間複雜度解決查詢第k大數問題優化演算法
之前用了個分治法用O(n)時間複雜度簡潔查詢diK大數的問題。可以參考下面部落格: 但是由於過於複雜,估計很多人都不想使用。 下面我用隨機法來解決這個問題吧,據複雜的數學分析隨機法的時間是少於4n的,而分治法反而是4n,所以其實隨機法更加優化了,而且更加重要的是更加簡單了
Manacher演算法解決最長迴文子串問題---O(n)時間複雜度
#include <iostream> #include <string.h> using namespace std; void Manacher(char *src) { char *str = new char[2*strlen(src)+3]; str[0]
python_lintcode_372在O(1)時間複雜度刪除連結串列節點_174刪除連結串列中倒數第n個節點
372在O(1)時間複雜度刪除連結串列節點 題目 給定一個單鏈表中的一個等待被刪除的節點(非表頭或表尾)。請在在O(1)時間複雜度刪除該連結串列節點。 樣例 Linked list is
求最大連續子序列的和,時間複雜度為 O(n)
練習題目 給定陣列 [ a0, a1, a2, …, an ] ,找出其最大連續子序列和,要求時間複雜度為 O(n),陣列包含負數。 例如:輸入 [ -2,11,-4,13,-5,-2] ,輸出 20(即 11 到 13)。 解答 關於這個問題有很多種解法,這裡介紹一種時間複雜度僅為 O(n)
長度為n的順序表L,編寫一個時間複雜度為O(n),空間複雜度為O(1)的演算法,該演算法刪除線性表中所有值為X的元素
解法:用K記錄順序表L中不等於X的元素個數,邊掃描L邊統計K,並將不等於X的元素向前放置K位置上,最後修改L長度 void del_x_1(SqList &L,Elemtype x){ int k=0; for(i=0;i<L.length;i++) {
將陣列排序,陣列中所有的負整數出現在正整數前面(時間複雜度為 O(n), 空間複雜度為 O(1)).
<pre name="code" class="plain">#include <stdio.h> #define N 10 void swap (int *a, int i,
最大子序列的和演算法-時間複雜度O(n)
#include<iostream> using namespace std; int MaxSubseqSum(int ar[],int n){ int ThisSum=0,MaxSu
陣列中只出現一次的數字,時間複雜度O(n),空間複雜度O(1)的解法
題目:一個整型數組裡除了兩個陣列外,其他的數字都出現了兩次,要找出這兩個數字。 異或運算有一個性質:任何數異或它自己,結果都是0;這樣如果題目變成只有一個數字只出現一次,其他數字均出現兩次,這樣我們從頭到尾異或陣列中的每一個數字,那麼最終的結果就是隻出現一次的數字
有1,2,....一直到n的無序陣列,求排序演算法,要求時間複雜度為O(n),空間複雜度O(1)
http://blog.csdn.net/dazhong159/article/details/7921527 1、有1,2,....一直到n的無序陣列,求排序演算法,並且要求時間複雜度為O(n),空間複雜度O(1),使用交換,而且一次只能交換兩個數。 #include &
718. Maximum Length of Repeated Subarray 字尾陣列解最長公共子串 O(n log^2 n)時間複雜度
題意 找最長公共子串 思路 用dp的方法很容易在O(n^2)解決問題,這裡主要討論用字尾陣列的思路解決這個問題 字尾數組裡有兩個經典的概念或者稱為資料結構,就是字尾陣列SA,以及高度陣列LCP SA陣列的定義是:將原串S所有的字尾按字典序排序
CVPR論文《100+ Times FasterWeighted Median Filter (WMF)》的實現和解析(附原始碼)。 任意半徑中值濾波(擴充套件至百分比濾波器)O(1)時間複雜度演算法的原理、實現及效果 任意半徑中值濾波(擴充套件至百分比濾波器)O(1)時間複雜度演算法的原理、實現及
四年前第一次看到《100+ Times FasterWeighted Median Filter (WMF)》一文時,因為他附帶了原始碼,而且還是CVPR論文,因此,當時也對程式碼進行了一定的整理和解讀,但是當時覺得這個演算法雖然對原始速度有不少的提高,但是還是比較慢。因此,沒有怎麼在意,這幾天有幾位朋友
最長遞增子序列 O nlgn時間複雜度
對於一個數字序列,請設計一個複雜度為O(nlogn)的演算法,返回該序列的最長上升子序列的長度,這裡的子序列定義為這樣一個序列U1,U2...,其中Ui < Ui+1,且A[Ui] < A[Ui+1]。 給定一個數字序列A及序列的長度n,請返回最長上升子序列的長度。 測試樣例: [2,1,4
O(logN)時間複雜度內求整數的N次方以及矩陣的N次方
整數N次方 假設一個整數是10,如何最快地求解10的75次方。 1. 75的二進位制數形式為1001011 2. 10的75次方=10^64 × 10^8 × 10^2 × 10^1 在這個過程中,我們先求出10^1,然後根據10^2,再根據10^2求出
合併兩個有序連結串列--實現1+2+3+....+n,時間複雜度為O(1)
1、合併兩個有序連結串列,合併以後的連結串列依舊有效 C語言實現 連結串列結點定義如下: typedef int DataType; typedef struct Node { DataType _data; struct Node*
最長遞增子序列(兩種時間複雜度演算法及其區別)+最長遞減子序列(reverse)
O(n*n)//LIS+路徑回溯 O(n*n) #include <iostream> #include<cstdio> #include<stack> #i