二分partition演算法是指在o(n)的時間複雜度和o(1)的空間複雜度的情況下將乙個陣列分為大於某個數和小於某個數的兩部分。快速排序其實就是分治+partition演算法。
int
partition
(vector<
int>
&nums,
int begin,
int end)
swap
(nums[pos]
, nums[begin]);
return pos;
}
在cpp的stl中的演算法庫提供了這個演算法的api:
std::
nth_element
(container, begin, end)
;
通過最基本的partition演算法,我們可以引用於求陣列的第k大的數,比如中位數。我們只需要不斷分成兩部分,然後將多的那部分繼續分成兩部分。直到兩邊一樣多。
int
findkthlargest
(vector<
int>
&nums,
int k)
else
if(pos < len-k)
left = pos+1;
else
right = pos;
}return res;
}
有的時候陣列中大小關係並不只是大於和小於,還有等於。所以如果我們想將乙個陣列劃分為小於x,等於x,大於x的三部分。那麼我們可以對二分partition進行簡單的改造就可以實現上面的需求了。
int
partition
(vector<
int>
&nums,
int begin,
int end)
return pos1;
}
當然也可以使用二分partition+三向切分來解決(荷蘭國旗問題), 三向切分的作用就是根據目標值分為大於,等於,小於三個部分。
void
wigglesort
(vector<
int>
& nums)
else
if(num[j]
< mid)
else
}}
單峰陣列求第k大演算法
單峰陣列實際上可以看成兩個有序的陣列,這個問題就轉變成了兩個有序陣列求第k大。容易想到的演算法是對這兩個陣列進行歸併,生成乙個新的有序陣列,求出第k大之後就可以立刻停止,複雜度是o k 的。但是還有更優的演算法,可以使用分治的思想 實際上也是一種二分 來計算。對於兩個有序的陣列a和b,取出他們第k ...
求序列第K大演算法總結
參考部落格 傳送門 在上面的部落格中介紹了求序列第k大的幾種演算法,感覺收益良多,其中最精巧的還是利用快速排序的思想o n 查詢的演算法。仔細學習以後我將其中的幾個實現了一下。解法 1 將亂序陣列從大到小進行排序然後取出前k大,總的時間複雜度為o nlogn 解法 2 利用選擇排序或互動排序,取出前...
求區間第k大
int a mx void insert int a,int l,int r int divide int a,int l,int r 劃分子問題 a l x return l int select int s,int l,int r,int k,int len 返回s陣列l r的第k大數的下標 w...