然后从小到大遍历 diff,累加变化量(类比积分的概念)。第 i 个人到达时,花的数目即为不超过 person}_i 时间点的变化量的累加值。
为了快速计算每个人的答案,我们需要将 person 从小到大排序,这样可以在遍历 person 的同时从小到大遍历 diff。
时间复杂度:O(n\log n + m\log m),其中 n 是 flowers 的长度,m 是 persons 的长度。
空间复杂度:O(n+m)。
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: deffullBloomFlowers(self, flowers: List[List[int]], persons: List[int]) -> List[int]: diff = defaultdict(int) # 也可以用 SortedDict for start, end in flowers: diff[start] += 1 diff[end + 1] -= 1 times = sorted(diff.keys())
n = len(persons) ans = [0] * n i = sum = 0 for p, idinsorted(zip(persons, range(n))): while i < len(times) and times[i] <= p: sum += diff[times[i]] # 累加变化量 i += 1 ans[id] = sum return ans
int n = persons.size(); vector<int> id(n); iota(id.begin(), id.end(), 0); sort(id.begin(), id.end(), [&](int i, int j) { return persons[i] < persons[j]; });
vector<int> ans(n); auto it = diff.begin(); int sum = 0; for (int i : id) { while (it != diff.end() && it->first <= persons[i]) sum += it++->second; // 累加变化量 ans[i] = sum; } return ans; } };
funcfullBloomFlowers(flowers [][]int, persons []int) []int { diff := map[int]int{} for _, f := range flowers { diff[f[0]]++ diff[f[1]+1]-- }
n := len(diff) times := make([]int, 0, n) for t := range diff { times = append(times, t) } sort.Ints(times)
for i, p := range persons { persons[i] = p<<32 | i } sort.Ints(persons)
ans := make([]int, len(persons)) i, sum := 0, 0 for _, p := range persons { for ; i < n && times[i] <= p>>32; i++ { sum += diff[times[i]] // 累加变化量 } ans[uint32(p)] = sum } return ans }
方法二:转换 + 二分
第 i 个人能看到的花的数目,等价于 start 不晚于 persons}_i 的花的数目,减去 end 早于 persons}_i 的花的数目,即开花数减去凋落数。
所以单独统计开花时间和凋落时间,排序后二分就得到了答案。
时间复杂度:O((n+m)\log n),其中 n 是 flowers 的长度,m 是 persons 的长度。
空间复杂度:O(n)。不计返回值的空间。
[sol2-Python3]
1 2 3 4 5
classSolution: deffullBloomFlowers(self, flowers: List[List[int]], persons: List[int]) -> List[int]: starts = sorted(s for s, _ in flowers) ends = sorted(e for _, e in flowers) return [bisect_right(starts, p) - bisect_left(ends, p) for p in persons]