注:这里用left和right来记录median左右元素总个数(假设已按大小排序);结合set[median]即median元素的个数,来判断median是否需要向左右调整。
#include <stdio.h>
#include <stack>
#include <stdlib.h>
#include <string.h>
using namespace std;
void adjust();
void adjustleft();
void adjustright();
stack<int> s;
int set[100001] = {0};
int m = 0;
int left = 0;
int right = 0;
int main(int argc, char *argv[]) {
char cmd[3][11] = {"Push", "Pop", "PeekMedian"};
int n;
scanf("%d", &n);
int i, j;
char in[20];
for (i = 0; i < n; i++) {
scanf("%s", in);
if (strcmp(in, cmd[1]) == 0) {
if (s.empty()) {
printf("Invalid\n");
} else {
int tmp = s.top();
printf("%d\n", tmp);
s.pop();
set[tmp]--;
if (tmp < m) left--;
else if (tmp > m) right--;
adjust();
}
} else if (strcmp(in, cmd[0]) == 0) {
int tmp;
scanf("%d", &tmp);
s.push(tmp);
set[tmp]++;
if (tmp < m) left++;
else if (tmp > m) right++;
adjust();
} else if (strcmp(in, cmd[2]) == 0) {
if (m != 0)
printf("%d\n", m);
else
printf("Invalid\n");
}
}
return 0;
}
void adjust() {
if (left + set[m] < right) {
adjustright();
} else if (left >= set[m] + right) {
adjustleft();
} else if (s.empty()) {
m = left = right = 0;
}
}
void adjustleft() {
right += set[m];
int t;
for (t = m - 1; set[t] == 0; t--);
m = t;
left -= set[m];
}
void adjustright() {
left += set[m];
int t;
for (t = m + 1; set[t] == 0; t++);
m = t;
right -= set[m];
}