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

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进people
    			people.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])
    		{
    			count++;
    			if(maxAlive < count)
	    		{
	    			maxAlive = count;
	    			year = birth[i];
	    		}
	    		i++;
	    	}
    		else
    		{
    			count--;
    			j++;
    		}
    	}
    	return year;
    }
};

在这里插入图片描述

发布了785 篇原创文章 · 获赞 1143 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/qq_21201267/article/details/105173243