文章目录

  • 1. 题目
  • 2. 解题
    • 2.1 优先队列
    • 2.2 双指针

1. 题目

给定N个人的出生年份和死亡年份,第i个人的出生年份为 birth[i],死亡年份为 death[i],实现一个方法以计算生存人数最多年份

你可以假设所有人都出生于1900年至2000年(含1900和2000)之间。
如果一个人在某一年的任意时期都处于生存状态,那么他们应该被纳入那一年的统计中。
例如,生于1908年、死于1909年的人应当被列入1908年和1909年的计数。

如果有多个年份生存人数相同且均为最大值,输出其中最小的年份。

示例:
输入:
birth = {1900, 1901, 1950}
death = {1948, 1951, 2000}
输出: 1901提示:
0 < birth.length == death.length <= 10000
birth[i] <= death[i]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/living-people-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 优先队列

  • 以时间为轴
  • 建立两个优先队列,baby 表示未出生的,people表示存活的
  • baby 按照出生时间出队,并 push 进 people,people 按照死亡时间 出队
  • 记录 people 的最大人数及年份
struct cmp1
{bool operator()(vector<int>& a, vector<int> &b){return a[0] > b[0];//出生时间的小顶堆}
};
struct cmp2
{bool operator()(vector<int>& a, vector<int> &b){return a[1] > b[1];//离开时间的小顶堆}
};
class Solution {public:int maxAliveYear(vector<int>& birth, vector<int>& death) {priority_queue<vector<int>,vector<vector<int>>,cmp1> baby;priority_queue<vector<int>,vector<vector<int>>,cmp2> people;vector<int> mostP_year(2,0);//人数——年份int time = 2000, maxPeople = 0;for(int i = 0; i < birth.size(); ++i){baby.push({birth[i],death[i]});time = min(time, birth[i]);}while(!baby.empty() || !people.empty()){while(!baby.empty() && baby.top()[0]==time){    //baby出生了,push进peoplepeople.push(baby.top());baby.pop();}if(people.size() > mostP_year[0]){   //更新最大人数mostP_year[0] = people.size();mostP_year[1] = time;}while(!people.empty() && people.top()[1]==time)people.pop();//people离开了,弹出time++;//白驹过隙,惜乎惜乎}return mostP_year[1];}
};

  • 将 baby 优先队列改为数组排序,省去 baby 出队时间
struct cmp2
{bool operator()(vector<int>& a, vector<int> &b){return a[1] > b[1];}
};
class Solution {public:int maxAliveYear(vector<int>& birth, vector<int>& death) {vector<vector<int>> baby;priority_queue<vector<int>,vector<vector<int>>,cmp2> people;vector<int> mostP_year(2,0);int time = 2000, maxPeople = 0, i;for(i = 0; i < birth.size(); ++i){baby.push_back({birth[i],death[i]});time = min(time, birth[i]);}sort(baby.begin(),baby.end(),[](vector<int>& a, vector<int> &b){return a[0] < b[0];});i = 0;while(i < baby.size() || !people.empty()){while(i < baby.size() && baby[i][0]==time){people.push(baby[i]);i++;}if(people.size() > mostP_year[0]){mostP_year[0] = people.size();mostP_year[1] = time;}while(!people.empty() && people.top()[1]==time)people.pop();time++;}return mostP_year[1];}
};

2.2 双指针

class Solution {public:int maxAliveYear(vector<int>& birth, vector<int>& death) {sort(birth.begin(), birth.end());//按出生时间排序sort(death.begin(), death.end());//按离开时间排序int i=0, j=0, count = 0, maxAlive = 0, year = 2020;while(i < birth.size()){if(birth[i] <= death[j]){   //新出生+1count++;if(maxAlive < count){maxAlive = count;year = birth[i];}i++;}else{  //离开一人 -1count--;j++;}}return year;}
};

程序员面试金典 - 面试题 16.10. 生存人数(自定义优先队列)相关推荐

  1. [Leetcode][程序员面试金典][面试题16.11][JAVA][跳水板][数学][动态规划]

    [问题描述][简单] [解答思路] 边界问题 k=0 ,不能产生跳水板,返回空数组 shorter 等于longer,只有一种跳水板,返回longerk 思路 一般情况,k块木板,k种可能 跳水板的长 ...

  2. java兰顿蚂蚁解题思路_程序员面试金典 - 面试题 16.22. 兰顿蚂蚁(deque模拟)

    1. 题目 一只蚂蚁坐在由白色和黑色方格构成的无限网格上. 开始时,网格全白,蚂蚁面向右侧. 每行走一步,蚂蚁执行以下操作. (1) 如果在白色方格上,则翻转方格的颜色,向右(顺时针)转 90 度,并 ...

  3. 程序员面试金典 - 面试题 16.16. 部分排序(排序/不排序)

    文章目录 1. 题目 2. 解题 2.1 排序 2.2 不排序 1. 题目 给定一个整数数组,编写一个函数,找出索引 m 和 n ,只要将索引区间 [m,n] 的元素排好序,整个数组就是有序的. 注意 ...

  4. 程序员面试金典 - 面试题 16.22. 兰顿蚂蚁(deque模拟)

    1. 题目 一只蚂蚁坐在由白色和黑色方格构成的无限网格上. 开始时,网格全白,蚂蚁面向右侧. 每行走一步,蚂蚁执行以下操作. (1) 如果在白色方格上,则翻转方格的颜色,向右(顺时针)转 90 度,并 ...

  5. 程序员面试金典 - 面试题 16.03. 交点(数学)

    1. 题目 给定两条线段(表示为起点start = {X1, Y1}和终点end = {X2, Y2}),如果它们有交点,请计算其交点,没有交点则返回空值. 要求浮点型误差不超过10^-6.若有多个交 ...

  6. 程序员面试金典 - 面试题 16.09. 运算(只用+法做乘除)

    1. 题目 请实现整数数字的乘法.减法和除法运算,运算结果均为整数数字, 程序中只允许使用加法运算符和逻辑运算符,允许程序中出现正负常数,不允许使用位运算. 你的实现应该支持如下操作: Operati ...

  7. 程序员面试金典 - 面试题 16.26. 计算器(栈)

    1. 题目 给定一个包含 正整数.加(+).减(-).乘(*).除(/)的算数表达式(括号除外),计算其结果. 表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 . 整数除法仅保留整数部分. ...

  8. 程序员面试金典 - 面试题 16.20. T9键盘(数组)

    1. 题目 在老式手机上,用户通过数字键盘输入,手机将提供与这些数字相匹配的单词列表. 每个数字映射到0至4个字母.给定一个数字序列,实现一个算法来返回匹配单词的列表. 你会得到一张含有有效单词的列表 ...

  9. 程序员面试金典 - 面试题 16.02. 单词频率(哈希表/Trie树)

    文章目录 1. 题目 2. 解题 2.1 哈希解法 2.2 Trie树 1. 题目 设计一个方法,找出任意指定单词在一本书中的出现频率. 你的实现应该支持如下操作: WordsFrequency(bo ...

最新文章

  1. 卓瑞机器人_校企合作专业共建记涪陵职教中心机器人专业中泰学术交流活动
  2. 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具
  3. file_put_contents图片固定大小_创意图片裁剪,神一样的操作
  4. java制作文本框中的表格输入List数据
  5. ThinikPHP 前端URL模式
  6. linux shell脚本编程技巧介绍(一)
  7. setTimeout还是setInterval?
  8. SQL查询-将列转换成字符串(for xml path)
  9. java提高数据库访问效率代码优化
  10. linux驱动_设备驱动_问题定位_vivo_pd1932_音量键
  11. SourceTree拉取代码出现错误
  12. NK-RTU980 USB bulk传输
  13. 【经验分享】突然我的SM.MS的图床没法访问了(内附解决方法)
  14. java编译器对字符串+运算的优化导致的有趣现象
  15. 思科曹图强:勒索软件将打破安全防御平衡
  16. 使用nginx代理访问外网
  17. 输入子系统(1)——框架认识
  18. 0001 零基础Maya插件开发——Python+Qtdesigner环境搭建
  19. Javascript算法实现PDF批量加盖不同宽度骑缝章,vue加持。
  20. C#中base关键字的详解

热门文章

  1. 大数据入门:各种大数据技术的介绍
  2. linux中的信号2——进程如何处理信号?
  3. opnet平台中切换模块的理解——切换的建模
  4. c#利用定时器自动备份数据库(mysql)
  5. 项目中cxf和weblogic整合时报错的问题
  6. LeetCode | HouseCode 算法题
  7. 使用data()方法缓存数据
  8. SQL基础---SQL AND OR 运算符
  9. c++现在有一棵合法的二叉树,树的节点都是用数字表示,现在给定这棵树上所有的父子关系,求这棵树的高度
  10. Linux驱动开发中与设备树相关的6种debug方法