732. My Calendar III

来源:互联网 发布:电脑音乐剪辑软件 编辑:程序博客网 时间:2024/04/30 07:27

Implement a MyCalendarThree class to store your events. A new event can always be added.

Your class will have one method, book(int start, int end). Formally, this represents a booking on the half open interval [start, end), the range of real numbers x such that start <= x < end.

A K-booking happens when K events have some non-empty intersection (ie., there is some time that is common to all K events.)

For each call to the method MyCalendar.book, return an integer K representing the largest integer such that there exists a K-booking in the calendar.

Your class will be called like this: MyCalendarThree cal = new MyCalendarThree(); MyCalendarThree.book(start, end)

Example 1:MyCalendarThree();MyCalendarThree.book(10, 20); // returns 1MyCalendarThree.book(50, 60); // returns 1MyCalendarThree.book(10, 40); // returns 2MyCalendarThree.book(5, 15); // returns 3MyCalendarThree.book(5, 10); // returns 3MyCalendarThree.book(25, 55); // returns 3

这一题一开始还是希望像之前的两题一样,只用一个无序的vector< pair< int, int>> 来遍历,一个数组存起始和终止的时间点组合,一个数组存对应的重复频率。每一次新的book都遍历是否有重复,有的话将重复部分,非重复部分都重新存入,始终保持每一个time slot都是separate的。这样可行,但是写起来很麻烦。

简洁做法:
构建一个map, map是一个有序的,key-value组合,每一个key都是unique的。内部实现是binary search tree。By the way, unordered_map内部是hash table.
代码如下:
每一次开始在对应时间+1,每一个结束都是-1,如果还没结束就开始了另一个+1,那就说明重复了一次。
基本原理如下,最后按照时间顺序找到某一个重复次数最多的时刻即可。

class MyCalendarThree {private:    map<int, int> mymap;public:    MyCalendarThree() {    }    int book(int start, int end) {        mymap[start]++;        mymap[end]--;        int res = 0;        int cur = 0;        for (auto e : mymap) {            cur += e.second;            res = max(res, cur);        }        return res;    }};

map and set:
map::insert

#include <iostream>#include <map>int main (){  std::map<char,int> mymap;  // first insert function version (single parameter):  mymap.insert ( std::pair<char,int>('a',100) );  mymap.insert ( std::pair<char,int>('z',200) );  std::pair<std::map<char,int>::iterator,bool> ret;  ret = mymap.insert ( std::pair<char,int>('z',500) );  if (ret.second==false) {    std::cout << "element 'z' already existed";    std::cout << " with a value of " << ret.first->second << '\n';  }  // second insert function version (with hint position):  std::map<char,int>::iterator it = mymap.begin();  mymap.insert (it, std::pair<char,int>('b',300));  // max efficiency inserting  mymap.insert (it, std::pair<char,int>('c',400));  // no max efficiency inserting  // third insert function version (range insertion):  std::map<char,int> anothermap;  anothermap.insert(mymap.begin(),mymap.find('c'));  return 0;}

这里值得注意的是,insert的返回值是一个pair 类型,如果想要判断插入是否成功以及获得插入的位置,可以用上述那种构造一个对应的pair. 或者用auto res = mymap.insert({a, 100}). res.first 就是一个指向插入位置的迭代器,res.second 就是一个true or false. 如果是false 代表插入失败,然后first是already exist的位置。
这里也可以用tie(a, b)来做。tie一般用来unpack pair 或者 tuple之类的数据。实现定义好a and b, 然后可以用tie 将返回值分别赋值给a and b。

map::erase

it=mymap.find('b');mymap.erase (it);                   // erasing by iteratormymap.erase ('c');                  // erasing by keyit=mymap.find ('e');mymap.erase ( it, mymap.end() );    // erasing by range

如果想要建立可以重复的key下的map,就要用multimap。
multimap的insert和erase用法与map几乎一致,对于重复元素,如果erase by iterator, 只删一个,如果erase by key, 都删了。find的时候,有多个,返回第一个的iterator。
对于重复问题的两个常用成员函数。count和equal_range.

// 统计key为"Jack"的数目      std::string strFind = "Jack";      unsigned int uCount = myMultiMap.count(strFind);      if (uCount == 0)      {          std::cout << "================Count " << strFind << ":0"<< std::endl;      }      else      {          std::cout << "================Count " << strFind << ":" << uCount << std::endl;          std::multimap<std::string, int>::iterator iter = myMultiMap.find(strFind);          if (iter != myMultiMap.end())          {              for (unsigned int i = 0; i < uCount; ++i)              {                  std::cout << (*iter).first << ":" << (*iter).second << std::endl;                  iter++;              }          }      }      std::cout << "================use equal_range"<< std::endl;      typedef std::multimap<std::string, int>::iterator MultiMapIterator;      std::pair<MultiMapIterator, MultiMapIterator> iterPair = myMultiMap.equal_range("Jack");      for (MultiMapIterator it = iterPair.first; it != iterPair.second; ++it)      {          std::cout << (*it).first << ":" << (*it).second << std::endl;      }  

equal_range 返回的是一个pair组合。两个元素分别是起始的iterator。

set 和multiset几乎是类似的设置。
都是基于平衡二叉树。只不过不是key-value的配置,只有key。

原创粉丝点击