public
static
intfindk
(int
nums,
int m,
int n ,
int k)
while
(i<=temp)
if(i} nums[m]
=nums[j]
; nums[j]
=temp;
if(j+
1==k)
else
if(j+
1>k)
else
}public
static
void
main
(string[
] args)
; system.out.
println
(findk
(nums,
0, nums.length-1,
4));
}
隨機選擇乙個數m(bfprt與上面的差別就在這裡,bfprt精挑細選乙個數,盡可能淘汰更多數)
m放右邊
命中返回,沒命中往左右選一邊繼續遞迴
如何選數
首先把陣列按5個數為一組進行分組,最後不足5個的忽略。對每組數進行排序(如插入排序)求取其中位數。o(n)
把上一步的所有中位數移到陣列的前面,對這些中位數遞迴呼叫bfprt演算法求得他們的中位數。
如需要得到m=【3,2,3】的中位數將上一步得到的中位數作為劃分的主元進行整個陣列的劃分。找第二個小的數
bfprt(m,2)
public
static
intbfprt_choose
(int
nums,
int m,
int n)
else
}return
findk
(q,0
, q.length-
1, q.length/2)
;}
這樣選 妙在**?
固定甩掉
n 10(
中位數)
+2∗n
10=3n
10個
數\frac(中位數)+2*\frac=\frac個數
10n(中
位數)+
2∗10
n=1
03n
個數最壞複雜度為o(n)
t (n
)=o(
n)+t
(n/5
)+o(
3n/10
)t(n
)=o(
n)
t(n)=o(n)+t(n/5)+o(3n/10) t(n)=o(n)
t(n)=o
(n)+
t(n/
5)+o
(3n/
10)t
(n)=
o(n)
master公式
t(n) = at(n/b) + o(n^d)
b:子過程的樣本量
a:子過程的計算次數
o(n^d):子結果合併的時間複雜度
滿足如上公式的程式都可以根據master公式計算時間複雜度:
log(b,a) > d :時間複雜度為o(n^log(b,a))
log(b,a) = d :時間複雜度為o(n^d * logn)
log(b,a) < d :時間複雜度為o(n^d)
演算法開創乙個時代
直接寫出時間複雜度表示式,可以推出演算法最後時間表示式,看怎麼樣這個演算法,值不值得研究。
BFPRT演算法O n 解決第k小的數
第k小演算法 我們通常會簡單地進行乙個快速排序後,得到第k個位置上的數字即可。我們都知道的是快速排序是個不穩定的排序,它的排序過程簡單的理解主要是兩個概念partion,pivot 基準數 一趟快速排序的過程如下 先從序列中選取乙個數作為基準數 將比這個數大的數全部放到它的右邊,把小於或者等於它的數...
演算法題 BFPRT演算法 求第K小或者第K大的數
2017 11 21 bfprt問題 乙個陣列中求第k小或者第k大的數 不通過排序求第k小的數,時間複雜度為o n 1 找到乙個劃分值,按照partition的過程,分為小於區 等於區 大於區,則可知等於區是在整個陣列有序後不變的部分。2 求第k小的數,就是陣列有序後下標為k 1的數。3 所以,如果...
快排擴充套件 第k小的數
使用快排中的partition方法,可以很快找到乙個無序序列中的第k小的數。思想 對於乙個陣列a 0.n 1 分段成a 0.st 1 a s a st 1.n 1 分組後,a 0.st 1 裡面的元素都小於等於a st a st 1.n 1 裡面的元素都大於等於a st 所以,如果 st k 1,那...