LeetCode 2251. 花期内花的数目

2251. 花期内花的数目

给你一个下标从 0 开始的二维整数数组 flowers ,其中 flowers[i] = [starti, endi] 表示第 i 朵花的 花期 从 starti 到 endi (都 包含)。同时给你一个下标从 0 开始大小为 n 的整数数组 people ,people[i] 是第 i 个人来看花的时间。

请你返回一个大小为 n 的整数数组 answer ,其中 answer[i]是第 i 个人到达时在花期内花的 数目 。

示例 1:

输入:flowers = [[1,6],[3,7],[9,12],[4,13]], people = [2,3,7,11]
输出:[1,2,2,2]
解释:上图展示了每朵花的花期时间,和每个人的到达时间。
对每个人,我们返回他们到达时在花期内花的数目。

示例 2:

输入:flowers = [[1,10],[3,3]], people = [3,3,2]
输出:[2,2,1]
解释:上图展示了每朵花的花期时间,和每个人的到达时间。
对每个人,我们返回他们到达时在花期内花的数目。

提示:

  • 1 <= flowers.length <= 5 * 10^4
  • flowers[i].length == 2
  • 1 <= starti <= endi <= 10^9
  • 1 <= people.length <= 5 * 10^4
  • 1 <= people[i] <= 10^9

提示 1

Notice that for any given time t, the number of flowers blooming at time t is equal to the number of flowers that have started blooming minus the number of flowers that have already stopped blooming.


提示 2

We can obtain these values efficiently using binary search.


提示 3

We can store the starting times in sorted order, which then allows us to binary search to find how many flowers have started blooming for a given time t.


提示 4

We do the same for the ending times to find how many flowers have stopped blooming at time t.

 

解法1:差分数组 + 有序哈希表 + 二分查找

关于类似题型的详解:LeetCode 1943. 描述绘画结果-CSDN博客

Java版:

class Solution {
    public int[] fullBloomFlowers(int[][] flowers, int[] people) {
        int n = people.length;
        int[] ans = new int[n];
        TreeMap<Integer, Integer> cnt = new TreeMap<>();
        for (int[] flower : flowers) {
            cnt.merge(flower[0], 1, Integer::sum);
            cnt.merge(flower[1] + 1, -1, Integer::sum);
        }

        int m = cnt.size();
        int[][] diff = new int[m][2];
        int id = 0;
        for (Map.Entry<Integer, Integer> entry: cnt.entrySet()) {
            diff[id][0] = entry.getKey();
            diff[id][1] = entry.getValue();
            if (id > 0) {
                diff[id][1] += diff[id - 1][1];
            }
            id++;
        }

        for (int i = 0; i < n; i++) {
            int l = 0;
            int r = m - 1;
            while (l <= r) {
                int mid = l + (r - l) / 2;
                if (diff[mid][0] <= people[i]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
            if (r >= 0) {
                ans[i] = diff[r][1];
            } else {
                ans[i] = 0;
            }
        }
        return ans;
    }
}

Pyhton3版:

from sortedcontainers import SortedDict

class Solution:
    def fullBloomFlowers(self, flowers: List[List[int]], people: List[int]) -> List[int]:
        cnt = SortedDict()
        for l, r in flowers:
            cnt[l] = cnt[l] + 1 if l in cnt else 1
            cnt[r + 1] = cnt[r + 1] - 1 if r + 1 in cnt else -1
        
        m = len(cnt)
        diff = [[0] * 2 for _ in range(m)]
        i = 0
        for k, v in cnt.items():
            diff[i] = [k, v]
            if i > 0:
                diff[i][1] += diff[i - 1][1]
            i += 1
        
        n = len(people)
        ans = [0] * n
        for i in range(n):
            l = 0 
            r = m - 1
            while l <= r:
                mid = l + (r - l) // 2
                if diff[mid][0] <= people[i]:
                    l = mid + 1
                else:
                    r = mid - 1
            if r >= 0:
                ans[i] = diff[r][1]
            else:
                ans[i] = 0
        return ans

复杂度分析

  • 时间复杂度:O(m + nlogm),其中 n 为数组 people 的长度,m 为数组 flowers的长度,最坏情况下哈希表的长度也为m。维护变化量有序哈希表的时间复杂度为 O(m),将有序哈希表转化为数组并遍历数组求前缀和的时间复杂度为 O(m),生成返回数组的时间复杂度为 O(nlogm)。总的时间复杂度 O(m + m + nlogm) = O(m + nlogm)
  • 空间复杂度:O(n + m),即为存储变化量的哈希表和数组的空间开销。

解法2:差分数组 + 哈希表 + 数组排序 + 二分查找

Java版:

class Solution {
    public int[] fullBloomFlowers(int[][] flowers, int[] people) {
        Map<Integer, Integer> cnt = new HashMap<>();
        for (int[] flower : flowers) {
            cnt.merge(flower[0], 1, Integer::sum);
            cnt.merge(flower[1] + 1, -1, Integer::sum);
        }
        int m = cnt.size();
        int[][] diff = new int[m][2];
        int id = 0;
        for (Map.Entry<Integer, Integer> entry : cnt.entrySet()) {
            diff[id][0] = entry.getKey();
            diff[id][1] = entry.getValue();
            id++;
        }

        Arrays.sort(diff, new Comparator<int[]>() {
            public int compare(int[] diff1, int[] diff2) {
                return diff1[0] - diff2[0];
            }
        });
        for (int i = 1; i < m; i++) {
            diff[i][1] += diff[i - 1][1];
        }

        int n = people.length;
        int[] ans = new int[n];
        for (int i = 0; i < n; i++) {
            int l = 0;
            int r = m - 1;
            while (l <= r) {
                int mid = l + (r - l) / 2;
                if (diff[mid][0] <= people[i]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
            ans[i] = r >= 0 ? diff[r][1] : 0;
        }
        return ans;
    }
}

Python3版:

class Solution:
    def fullBloomFlowers(self, flowers: List[List[int]], people: List[int]) -> List[int]:
        cnt = defaultdict(lambda: 0)
        for l, r in flowers:
            cnt[l] += 1
            cnt[r + 1] -= 1
        
        m = len(cnt)
        diff = sorted([[k, v] for k, v in cnt.items()])
        for i in range(1, m):
            diff[i][1] += diff[i - 1][1]
        
        ans = [] 
        for p in people:
            l = 0
            r = m - 1
            while l <= r:
                mid = l + (r - l) // 2
                if diff[mid][0] <= p:
                    l = mid + 1
                else:
                    r = mid - 1
            if r >= 0:
                ans.append(diff[r][1])
            else:
                ans.append(0)
        return ans

复杂度分析

  • 时间复杂度:O((m + n) logm),其中 n 为数组 people 的长度,m 为 数组 flowers 的长度。维护变化量哈希表的时间复杂度为 O(m),将哈希表转化为数组并排序的时间复杂度为 O(mlogm),遍历数组求前缀和的时间复杂度为 O(m),生成返回数组的时间复杂度为 O(nlogm)。总的时间复杂度 O(m + m + mlogm + m + nlogm) = O((m + n) logm)
  • 空间复杂度:O(n + m),即为存储变化量的哈希表和数组的空间开销。
  • 36
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值