zoukankan      html  css  js  c++  java
  • Dynamic Median

    题意:

    设计一个数据结构,初始为空,支持以下操作:

    (1)增加一个元素,要求在log(n)时间内完成,其中n是该数据结构中当前元素的个数。注意:数据结构中允许有重复的元素。

    (2)返回当前元素集合的中位数,要求在常数时间内完成。如果当前元素的个数为偶数,那么返回下中位数(即两个中位数中较小的一个)。

    (3)删除中位数,要求在log(n)时间内完成。

    输入输入的第一行是一个自然数T,代表测试数据的组数((1 ≤ T ≤ 600))。每组测试数据的第一行是个自然数N,代表操作的次数,1<=N<=10000。后面的N行中的每行代表一个操作,每次操作首先输入一个单字符代表操作的类型:

    I表示插入,后面跟着输入一个正整数(这是唯一带有输入数值的操作)。
    Q表示查询,输出当前的中位数(这是唯一产生输出的操作)。
    D表示删除当前的中位数。

    输入保证是正确的:查询时集合保证不为空(即中位数是存在的),删除时保证集合中有足够可供删除的元素。输出每次查询操作Q时输出的中位数,每次输出单独占一行。

    样例输入

    1
    8
    I 4
    I 3
    I 5
    Q  
    D
    I 10
    I 2
    Q

    样例输出

    4
    3

    思路:

    维护两个堆,一个小顶堆(存放大于中位数的数),一个大顶堆(存放小于或等于中位数的数)。保持大顶堆的元素个数和小顶堆的元素个数相等(元素总数为偶数)或者大顶堆元素个数比小顶堆的元素个数多一个(元素总数为奇数)。此时,下中位数即为大顶堆堆顶元素。

    实现:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <functional>
     4 #include <queue>
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     ios::sync_with_stdio(false);
    10     int T, n, d;
    11     char c;
    12     cin >> T;
    13     while (T--)
    14     {
    15         priority_queue<int, vector<int>, greater<int>> minq;
    16         priority_queue<int> maxq;
    17         cin >> n;
    18         int cnt = 0;
    19         for (int i = 0; i < n; i++)
    20         {
    21             cin >> c;
    22             if (c == 'I')
    23             { 
    24                 cin >> d;
    25                 if (cnt == 0)
    26                 {
    27                     maxq.push(d);
    28                 }
    29                 else if (d > maxq.top())
    30                 {
    31                     if (cnt & 1)
    32                     {
    33                         minq.push(d);
    34                     }
    35                     else
    36                     {
    37                         minq.push(d);
    38                         maxq.push(minq.top());
    39                         minq.pop();
    40                     }
    41                 }
    42                 else
    43                 {
    44                     if (cnt & 1)
    45                     {
    46                         maxq.push(d);
    47                         minq.push(maxq.top());
    48                         maxq.pop();
    49                     }
    50                     else
    51                     {
    52                         maxq.push(d);
    53                     }
    54                 }
    55                 cnt++;
    56             }
    57             else if (c == 'Q')
    58             {
    59                 cout << maxq.top() << endl;
    60             }
    61             else
    62             {
    63                 if (cnt & 1)
    64                 {
    65                     maxq.pop();
    66                 }
    67                 else
    68                 {
    69                     maxq.pop();
    70                     maxq.push(minq.top());
    71                     minq.pop();
    72                 }
    73                 cnt--;
    74             }
    75         }
    76     }
    77     return 0;
    78 }
    
    
  • 相关阅读:
    LeetCode偶尔一题 —— 617. 合并二叉树
    《剑指offer》 —— 链表中倒数第k个节点
    《剑指offer》 —— 青蛙跳台阶问题
    《剑指offer》—— 二维数组中的查找
    《剑指offer》—— 替换空格
    《剑指offer》—— 合并两个排序的链表
    《剑指offer》—— 礼物的最大价值
    生成Nuget 源代码包来重用你的Asp.net MVC代码
    Pro ASP.Net Core MVC 6th 第四章
    Pro ASP.NET Core MVC 6th 第三章
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6383087.html
Copyright © 2011-2022 走看看