依序輸入多個數字,如何有效率找出中位數(median)?
例如:依序輸入7、13、2、6、9,中位數為7。
解法:
- 將所有數字排序,即可以得出中位數。
時間複雜度為$O(nlogn)$ 利用max heap和min heap:
- 新增數字到heap:
- 若max heap為空,數字新增到min heap。
- 若max heap不為空並且數字小於max heap的root,數字新增到max heap。
- 若max heap不為空並且數字大於max heap的root,數字新增到min heap。
- rebalance:
- 若max heap size - min heap size > 1, 刪除max heap的root並且新增到min heap。
- 若min heap size - max heap size > 1, 刪除min heap的root並且新增到max heap。
- 計算中位數:
- 若max heap size > min heap size,中位數為max heap的root。
- 若max heap size < min heap size,中位數為min heap的root。
- 若max heap size == min heap size,中位數為$(max\ heap的root + min\ heap的root) / 2$ (根據定義決定)。
時間複雜度為$O(1)$
此方法是利用中位數的特性:
左半部的數字一定小部右半邊。
例如:2、3、7、13、15 或是2、3、7、13、15
左半部和右半部的大小差值不能超過1,否則不能透過上述方法找出中位數。
左半部的數字(包含中位數)建成max heap,max heap的root即為中位數。
例如:2、3、7、13、15
2、3、7建成max heap,13、15建成min heap
右半部的數字(包含中位數)建成min heap,min heap的root即為中位數。
例如:2、3、7、13、15
2、3建成max heap,7、13、15建成min heap
- 新增數字到heap:
程式碼:
1 | import java.util.Collections; |