Day 3: Lintcode【区间】【中等】【数飞机+找名人】

1.数飞机
题目
给出飞机的起飞和降落时间的列表,用序列 interval 表示. 请计算出天上同时最多有多少架飞机?
如果多架飞机降落和起飞在同一时刻,我们认为降落有优先权。
Given an list interval, which are taking off and landing time of the flight. How many airplanes are there at most at the same time in the sky?
If landing and taking off of different planes happen at the same time, we consider landing should happen at first.

思路:
这题本人菜鸡。。也不会做,参考了网上大神的做法,大神们使用了各式各样的数据结构,可惜我还没复习。。定义一个类做的。(里面复习了构造函数的另一种简便写法;还有运算符的重载;)最最主要的思想就是**“化线为点”**。

  • 数每个区间的飞机数目,其实可以用端点的飞机数来代替。所以将每个区间的start点,end点都放到一起排序。(排序这里需要注意的是当时刻相等的时候,降落的优先级比起飞的高,这是题目规定的)。

  • 排序完扫描,遇到起飞点就飞机数目++;否则飞机数目–。过程中不断更新记录的最大值。

  • 返回最大值。
    代码:

      /**
       * Definition of Interval:
       * classs Interval {
       *     int start, end;
       *     Interval(int start, int end) {
       *         this->start = start;
       *         this->end = end;
       *     }
       * }
       */
      class Tpoint{
      public:
          int point;
          int flag;
          Tpoint(int point, int flag):point(point), flag(flag){}
          bool operator <(const Tpoint &rhs)const{
              return point < rhs.point || (point==rhs.point && flag<rhs.flag);
          }
      };
      
      class Solution {
      public:
          /**
           * @param airplanes: An interval array
           * @return: Count of airplanes are in the sky.
           */
          int countOfAirplanes(vector<Interval> &airplanes) {
              // write your code here
              int n = airplanes.size();
              vector<Tpoint>p;
              for(int i=0; i<n; ++i){
                  p.push_back(Tpoint(airplanes[i].start,1));
                  p.push_back(Tpoint(airplanes[i].end,0));
              }
              sort(p.begin(), p.end());
              
              int cnt = 0;
              int res = 0;
              for(int i=0; i<2*n; ++i){
                  if(p[i].flag==1)
                      cnt++;
                  else
                      cnt--;
                  res = max(res, cnt);
              }
              return res;
          }
      };
    

在这里插入图片描述

2.找名人

题目:
假设你和 n 个人在一个聚会中(标记为 0 到 n - 1),其中可能存在一个名人。名人的定义是所有其他 n - 1 人都认识他/她,但他/她不知道任何一个。
现在你想要找出这个名人是谁或者验证这个名人不存在。你唯一可以做的事情就是提出如下问题:“你好,A,你认识B吗?” 来获取A是否认识B。您需要通过询问尽可能少的问题(以渐近的意义)来找出名人是谁(或验证其不存在)。

你得到一个辅助函数 bool know(a,b),它会告诉你A是否知道B.实现一个函数 int findCelebrity(n),你的函数应该使 knows 的调用次数最少。

如果在这个聚会中有名人, 那么有且只有一个。如果有名人在聚会中则返回名人的标签,如果没有名人,返回 -1。

Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them.

Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do is to ask questions like: “Hi, A. Do you know B?” to get information of whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense).

You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int findCelebrity(n), your function should minimize the number of calls to knows.
There will be exactly one celebrity if he/she is in the party. Return the celebrity’s label if there is a celebrity in the party. If there is no celebrity, return -1.

思路:(参考大神)
每一次询问都不浪费怎么使用呢?
使用knows查询a认不认识b,如果a认识b则a一定不是名人,有希望的是b;如果a不认识b则b一定不是名人,有希望的是a。所以我们询问n-1此能找出最有希望的那个人。

虽然他最有希望,还可能存在一些人不认识他,一些人认识他。所以要再来2*(n-1)次询问。如果有上述情况,则返回-1说明没有名人。

最后返回最有希望的那个人(已经证实他就是名人)

代码:参考九章

// Forward declaration of the knows API.
bool knows(int a, int b);

class Solution {
public:
    /**
     * @param n a party with n people
     * @return the celebrity's label or -1
     */
    int findCelebrity(int n) {
        // Write your code here
        int someone=0;
        for(int i=1; i<n; ++i){
            if(knows(someone,i))
                someone=i;
        }
        
        for(int i=0; i<n; ++i){
            if(someone!=i && knows(someone,i)) return -1;
            if(someone!=i&& (!knows(i,someone)) ) return -1;
        }
        return someone;
    }
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值