1. 程式人生 > >1057. Stack (30)五種解法總結(大雜燴)

1057. Stack (30)五種解法總結(大雜燴)

Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack. With N elements, the median value is defined to be the (N/2)-th smallest element if N is even, or ((N+1)/2)-th if N is odd.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<= 105). Then N lines follow, each contains a command in one of the following 3 formats:

Push key
Pop
PeekMedian

where key is a positive integer no more than 105.

Output Specification:

For each Push command, insert key into the stack and output nothing. For each Pop or PeekMedian command, print in a line the corresponding returned value. If the command is invalid, print "Invalid" instead.

Sample Input:
17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop
Sample Output:
Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid

解題思路

  題目的大意是維護一個能隨時返回中位數的棧,這個問題其實可以直接簡化為維護一個能返回中位數同時支援插入和刪除的資料結構。本身解法比較多樣,網上能找到的解法有三種,個人感覺都很有啟發性,所以加上我的解法在此做個總結。      因為題目中說明每個資料都在[1,100000]之間,所以很樸素的一種解法就是設立一個Count[100005]。插入n的時候Count[n]++,刪除的時候Count[n]--,查詢的時候遍歷陣列,尋找字首和為(size+1)/2的下標。但是10^5本身是個比較大的數字,在多次查詢之後果斷超時了,怎麼辦呢?當然要做優化。

1.樹狀陣列+二分查詢

樹狀陣列(Binary Indexed Tree(BIT))是一種能高效查詢字首和的資料結構,具體實現原理見鄙人還沒寫好的拙作《樹狀陣列的複習》。使用樹狀陣列是為了能進行二分查詢,原先遍歷Count陣列,最多的時候能遍歷10^5次,運用二分查詢可以將查詢次數優化為lg(10^5)/lg(2)  < 15

下面是程式碼