【Leetcode】1854. Maximum Population Year

题目地址:

https://leetcode.com/problems/maximum-population-year/

给定一个长 n n n数组 A A A A A A里的元素都是数对,代表着一个人的生卒年。问人口最多的那一年是哪年。若答案不唯一则返回数值最小的年份。对于卒年,那个人不计入人口。

法1:扫描线。先将每一年份和生卒的信息存进一个class里,然后对所有的时间点排序(时间相同则卒先生后,这主要是因为题目的规定,一个人在其卒年是不计入人口的),接着直接扫描所有时间点,找到人口最多的年份里第一年即可。代码如下:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    
    class TimeStamp implements Comparable<TimeStamp> {
    	// flag是1代表生,0代表卒
        int time, flag;
        
        public TimeStamp(int time, int flag) {
            this.time = time;
            this.flag = flag;
        }
        
        @Override
        public int compareTo(TimeStamp o) {
            if (time != o.time) {
                return Integer.compare(time, o.time);
            }
            
            // 如果时间相同,则卒先生后
            return Integer.compare(flag, o.flag);
        }
    }
    
    public int maximumPopulation(int[][] logs) {
        List<TimeStamp> list = new ArrayList<>();
        for (int[] log : logs) {
            list.add(new TimeStamp(log[0], 1));
            list.add(new TimeStamp(log[1], 0));
        }
        
		list.sort((t1, t2) -> t1.compareTo(t2));
        
        int res = 0, cnt = 0, maxCnt = 0;
        for (TimeStamp timeStamp : list) {
            if (timeStamp.flag == 1) {
                cnt++;
            } else {
                cnt--;
            }
            
            if (cnt > maxCnt) {
                maxCnt = cnt;
                res = timeStamp.time;
            }
        }
        
        return res;
    }
}

时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空间 O ( n ) O(n) O(n)

法2:差分数组。其实是暴力法,即直接开个数组,统计每年的人口,然后枚举每个人的生卒做计数。由于要实现区间加数操作,所以可以用差分数组来优化,使得每次加数时间复杂度降为 O ( 1 ) O(1) O(1)。代码如下:

public class Solution {
    final int BASE = 1950;
    
    public int maximumPopulation(int[][] logs) {
        int[] diff = new int[101];
        for (int[] log : logs) {
            diff[log[0] - BASE]++;
            diff[log[1] - BASE]--;
        }
        
        int[] pop = new int[101];
        pop[0] = diff[0];
        for (int i = 1; i < diff.length; i++) {
            pop[i] = pop[i - 1] + diff[i];
        }
        
        int res = -1, cnt = 0;
        for (int i = 0; i < pop.length; i++) {
            if (pop[i] > cnt) {
                cnt = pop[i];
                res = i + BASE;
            }
        }
        
        return res;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值