1057. Stack (30)

来源:互联网 发布:查询java类库的文件 编辑:程序博客网 时间:2024/05/22 03:23

一、题目

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:
17PopPeekMedianPush 3PeekMedianPush 2PeekMedianPush 1PeekMedianPopPopPush 5Push 4PeekMedianPopPopPopPop
Sample Output:
InvalidInvalid322124453Invalid

二、分析

    看到该题目,第一反应是 PeekMedian 时将现有所有数利用 nth_element() 找到中位数输出,然而这样是超时的。其实,在 Push 与 Pop 操作时可以动态维护 median,由于所有 Push 入栈的数不大于100000,我们可以构造一个直方图,以保存 1~100000所有数的直方分布。分 Push 与 Pop 两种情况动态维护 median,median 为当前栈内所有数的中位数,count 为栈内所有 <= median 数的个数。

2.1 Push

    Push 又分为两种:

  • median < num:由于 num 的加入,可能会使中位数右移,如果确实右移了,则依次往右寻找,找到第一个直方图个数不为 0 的数,然后更新 median 与 count;
  • median >= num : 此时由于 num 的加入,可能会使中位数左移,类似于上一种情况的处理,只不过是往左寻找;

2.2 Pop

    Pop 与 Push 雷同,也是分两种情况处理,只不过与 Push 的情况稍有不同。

三、代码

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define MAX_INTEGER 100005int hist[MAX_INTEGER];inline int medianPostion(int n){return n % 2 ? (n + 1) / 2 : n / 2;}int main(){int n;scanf("%d", &n);vector<int> s;fill_n(hist, MAX_INTEGER, 0);int median = 0, count = 0;for(int i = 0; i < n; ++i){char cmd[15];scanf("%s", cmd);if(strcmp(cmd, "Push") == 0){int num;scanf("%d", &num);s.push_back(num);++hist[num];// the number is greater than the current medianif(median < num){if(count < medianPostion(s.size())){while(hist[++median] == 0) ;count += hist[median];}}else{++count;if(count - hist[median] >= medianPostion(s.size())){count -= hist[median];while(hist[--median] == 0) ;}}}else{if(s.empty()){printf("Invalid\n");continue;}if(strcmp(cmd, "Pop") == 0){int num = s.back();printf("%d\n", num);s.pop_back();--hist[num];// the number is greater than the current medianif(median < num){if(count - hist[median] >= medianPostion(s.size())){count -= hist[median];while(hist[--median] == 0) ;}}else{--count;if(count < medianPostion(s.size())){while(hist[++median] == 0) ;count += hist[median];}}}else{printf("%d\n", median);}}}return 0;}

0 0
原创粉丝点击