zoukankan      html  css  js  c++  java
  • 数据结构与算法(1)支线任务8——Find Median from Data Stream

    题目如下:(https://leetcode.com/problems/find-median-from-data-stream/)

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

    Examples: 

    [2,3,4] , the median is 3

    [2,3], the median is (2 + 3) / 2 = 2.5

    Design a data structure that supports the following two operations:

      • void addNum(int num) - Add a integer number from the data stream to the data structure.
      • double findMedian() - Return the median of all elements so far.

    题目需要实现两个函数:向一个整数表中添加元素以及找中位数。以下是两个思路:

    思路一

    如果用vector储存整数,找中位数较容易(O(1)),添加整数可能会较耗时间,于是尝试使用时间复杂度为O(log(n))的二分插入。

     1 class MedianFinder {
     2 public:
     3     bool odd; //长度是否为奇数。奇数为true,偶数为false
     4     int begin, end, mid; //数组头、尾、中间的下标
     5     vector<int> l; //数组
     6 
     7     MedianFinder(): odd(false), begin(0), end(0), mid(0) {}
     8 
     9     //添加整数
    10     void addNum(int num) {
    11         //更新
    12         odd = odd ? false : true;
    13         begin = 0;
    14         end = l.size() - 1;
    15         //二分查找
    16         while (begin <= end)
    17         {
    18             mid = (begin + end) / 2;
    19             if (l[mid] == num)
    20             {
    21                 break;
    22             }
    23             else if (l[mid] > num)
    24             {
    25                 end = mid - 1;
    26             } 
    27             else
    28             {
    29                 begin = mid + 1;
    30             }
    31         }
    32         //插入
    33         if (begin > end)
    34         {
    35             l.insert(l.begin()+begin, num);
    36         } 
    37         else
    38         {
    39             l.insert(l.begin()+mid, num);
    40         }
    41     }
    42 
    43     //返回中位数
    44     double findMedian() {
    45         begin = 0;
    46         end = l.size() - 1;
    47         mid = (begin + end) / 2;
    48         if (odd)
    49         {
    50             return l[mid];
    51         } 
    52         else
    53         {
    54             return ((double)l[mid] + l[mid+1]) / 2;
    55         }
    56     }
    57 };
    View Code

    思路二

    题目的提示说要用堆,于是考虑stl中的优先队列。可以将中位数两侧的数据分别储存至两个优先队列,一个整数大的优先级高(默认)(相当于排好序的大顶堆),另一个整数小的优先级高(相当于排好序的小顶堆)。

     1 class MedianFinder {
     2 public:
     3     bool odd; //长度是否为奇数。奇数为true,偶数为false
     4     priority_queue<int> front; //数组的前半部分,优先队列默认为较大的优先级高
     5     priority_queue<int, vector<int>, greater<int>> back; //数组的后半部分,较小的数优先级高
     6     
     7     MedianFinder(): odd(false) {}
     8 
     9     //添加整数
    10     void addNum(int num) {
    11         //更新长度的状态
    12         odd = odd ? false : true;
    13         //插入num,并保证front长度不小于back长度
    14         if (odd)
    15         {
    16             if (back.size() && num > back.top())
    17             {
    18                 back.push(num);
    19                 front.push(back.top());
    20                 back.pop();
    21             } 
    22             else
    23             {
    24                 front.push(num);
    25             }
    26         } 
    27         else
    28         {
    29             if (front.size() && num > front.top())
    30             {
    31                 back.push(num);
    32             } 
    33             else
    34             {
    35                 front.push(num);
    36                 back.push(front.top());
    37                 front.pop();
    38             }
    39         }
    40     }
    41 
    42     //返回中位数
    43     double findMedian() {
    44         if (odd)
    45         {
    46             return front.top();
    47         } 
    48         else
    49         {
    50             return ((double)front.top() + back.top()) / 2;
    51         }
    52     }
    53 };
    View Code

    附:

    //先留个坑,考完试再填吧……

  • 相关阅读:
    [原创]RTX使用printf输出后进入hardfault中断的处理方法
    [原创]单片机 HexToStr and HexToBcd BcdToStr
    [原创]单片机-HexToStr or HexToAsc
    再看 AspriseOCR
    [源创] STM32F103ZET6 基于XMODEM 通讯的 BOOTLOADER案列IAP
    单片机串口——如何判定接收一帧数据的完成
    [原创] 关于步科eview人机界面HMI的使用
    [原创] STM32 定时器TIMx 编码器应用 函数 TIM_EncoderInterfaceConfig 分析
    单片机的 HexToStr HexToBcd BcdToStr 几个转换函数
    [转载] 全局键盘钩子(WH_KEYBOARD)
  • 原文地址:https://www.cnblogs.com/permitato/p/5092546.html
Copyright © 2011-2022 走看看