Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 251 additions & 24 deletions solution/2200-2299/2251.Number of Flowers in Full Bloom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,17 @@

<!-- 这里可写通用的实现逻辑 -->

离散差分+离散查询
**方法一:排序 + 二分查找**

- 按开始时间对鲜花进行排序
- 按结束时间对鲜花进行排序
- 在每个人的新花数组中执行二分搜索
- 对按开始时间排序的花进行分析,`bisect_right` 给出给定人员考虑的最后一朵花
- 对按结束时间排序的花执行 `flowers` 操作`bisect_left`,给出针对给定人员考虑的第一朵花
- 两者相减,就得到当时盛开的花朵
我们将花按照开始时间和结束时间分别排序,然后对于每个人,我们可以使用二分查找来找到他们到达时在花期内花的数目。就是说,找出在每个人到达时,已经开花的花的数目,减去在每个人到达时,已经凋谢的花的数目,即可得到答案。

时间复杂度 $O((m + n) \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 $flowers$ 和 $persons$ 的长度。

**方法二:差分 + 排序 + 离线查询**

我们可以利用差分来维护每个时间点的花的数目。接下来,我们将 $persons$ 按照到达时间从小到大排序,在每个人到达时,我们对差分数组进行前缀和运算,就可以得到答案。

时间复杂度 $O(m \times \log m + n \times \log n)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是数组 $flowers$ 和 $persons$ 的长度。

<!-- tabs:start -->

Expand All @@ -72,38 +75,262 @@ class Solution:
return [bisect_right(start, p) - bisect_left(end, p) for p in persons]
```

```python
class Solution:
def fullBloomFlowers(self, flowers: List[List[int]], people: List[int]) -> List[int]:
d = defaultdict(int)
for st, ed in flowers:
d[st] += 1
d[ed + 1] -= 1
ts = sorted(d)
s = i = 0
m = len(people)
ans = [0] * m
for t, j in sorted(zip(people, range(m))):
while i < len(ts) and ts[i] <= t:
s += d[ts[i]]
i += 1
ans[j] = s
return ans
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
public int[] fullBloomFlowers(int[][] flowers, int[] people) {
int n = flowers.length;
int[] start = new int[n];
int[] end = new int[n];
for (int i = 0; i < n; ++i) {
start[i] = flowers[i][0];
end[i] = flowers[i][1];
}
Arrays.sort(start);
Arrays.sort(end);
int m = people.length;
int[] ans = new int[m];
for (int i = 0; i < m; ++i) {
ans[i] = search(start, people[i] + 1) - search(end, people[i]);
}
return ans;
}

private int search(int[] nums, int x) {
int l = 0, r = nums.length;
while (l < r) {
int mid = (l + r) >> 1;
if (nums[mid] >= x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
}
```

```java
class Solution {
public int[] fullBloomFlowers(int[][] flowers, int[] people) {
TreeMap<Integer, Integer> d = new TreeMap<>();
for (int[] f : flowers) {
d.merge(f[0], 1, Integer::sum);
d.merge(f[1] + 1, -1, Integer::sum);
}
int s = 0;
int m = people.length;
Integer[] idx = new Integer[m];
for (int i = 0; i < m; i++) {
idx[i] = i;
}
Arrays.sort(idx, Comparator.comparingInt(i -> people[i]));
int[] ans = new int[m];
for (int i : idx) {
int t = people[i];
while (!d.isEmpty() && d.firstKey() <= t) {
s += d.pollFirstEntry().getValue();
}
ans[i] = s;
}
return ans;
}
}
```

### **C++**

```cpp
class Solution {
public:
vector<int> fullBloomFlowers(vector<vector<int>>& flowers, vector<int>& people) {
int n = flowers.size();
vector<int> start;
vector<int> end;
for (auto& f : flowers) {
start.push_back(f[0]);
end.push_back(f[1]);
}
sort(start.begin(), start.end());
sort(end.begin(), end.end());
vector<int> ans;
for (auto& p : people) {
auto r = upper_bound(start.begin(), start.end(), p) - start.begin();
auto l = lower_bound(end.begin(), end.end(), p) - end.begin();
ans.push_back(r - l);
}
return ans;
}
};
```

```cpp
class Solution {
public:
vector<int> fullBloomFlowers(vector<vector<int>>& flowers, vector<int>& people) {
map<int, int> d;
for (auto& f : flowers) {
d[f[0]]++;
d[f[1] + 1]--;
}
int m = people.size();
vector<int> idx(m);
iota(idx.begin(), idx.end(), 0);
sort(idx.begin(), idx.end(), [&](int i, int j) {
return people[i] < people[j];
});
vector<int> ans(m);
int s = 0;
for (int i : idx) {
int t = people[i];
while (!d.empty() && d.begin()->first <= t) {
s += d.begin()->second;
d.erase(d.begin());
}
ans[i] = s;
}
return ans;
}
};
```

### **Go**

```go
func fullBloomFlowers(flowers [][]int, people []int) (ans []int) {
n := len(flowers)
start := make([]int, n)
end := make([]int, n)
for i, f := range flowers {
start[i] = f[0]
end[i] = f[1]
}
sort.Ints(start)
sort.Ints(end)
for _, p := range people {
r := sort.SearchInts(start, p+1)
l := sort.SearchInts(end, p)
ans = append(ans, r-l)
}
return
}
```

```go
func fullBloomFlowers(flowers [][]int, people []int) []int {
d := map[int]int{}
for _, f := range flowers {
d[f[0]]++
d[f[1]+1]--
}
ts := []int{}
for t := range d {
ts = append(ts, t)
}
sort.Ints(ts)
m := len(people)
idx := make([]int, m)
for i := range idx {
idx[i] = i
}
sort.Slice(idx, func(i, j int) bool { return people[idx[i]] < people[idx[j]] })
ans := make([]int, m)
s, i := 0, 0
for _, j := range idx {
t := people[j]
for i < len(ts) && ts[i] <= t {
s += d[ts[i]]
i++
}
ans[j] = s
}
return ans
}
```

### **TypeScript**

```ts
function fullBloomFlowers(flowers: number[][], persons: number[]): number[] {
// 离散差分
let hashMap = new Map();
for (let [start, end] of flowers) {
end++;
hashMap.set(start, (hashMap.get(start) || 0) + 1);
hashMap.set(end, (hashMap.get(end) || 0) - 1);
function fullBloomFlowers(flowers: number[][], people: number[]): number[] {
const n = flowers.length;
const start = new Array(n).fill(0);
const end = new Array(n).fill(0);
for (let i = 0; i < n; ++i) {
start[i] = flowers[i][0];
end[i] = flowers[i][1];
}
start.sort((a, b) => a - b);
end.sort((a, b) => a - b);
const ans: number[] = [];
for (const p of people) {
const r = search(start, p + 1);
const l = search(end, p);
ans.push(r - l);
}
for (let p of persons) {
if (!hashMap.has(p)) {
hashMap.set(p, 0);
return ans;
}

function search(nums: number[], x: number): number {
let l = 0;
let r = nums.length;
while (l < r) {
const mid = (l + r) >> 1;
if (nums[mid] >= x) {
r = mid;
} else {
l = mid + 1;
}
}
let keys = Array.from(hashMap.keys()).sort((a, b) => a - b);
let pre = 0;
for (let k of keys) {
pre += hashMap.get(k);
hashMap.set(k, pre);
return l;
}
```

```ts
function fullBloomFlowers(flowers: number[][], people: number[]): number[] {
const d: Map<number, number> = new Map();
for (const [st, ed] of flowers) {
d.set(st, (d.get(st) || 0) + 1);
d.set(ed + 1, (d.get(ed + 1) || 0) - 1);
}
const ts = [...d.keys()].sort((a, b) => a - b);
let s = 0;
let i = 0;
const m = people.length;
const idx: number[] = [...Array(m)]
.map((_, i) => i)
.sort((a, b) => people[a] - people[b]);
const ans = Array(m).fill(0);
for (const j of idx) {
const t = people[j];
while (i < ts.length && ts[i] <= t) {
s += d.get(ts[i])!;
++i;
}
ans[j] = s;
}
// 离散查询
let ans = persons.map(v => hashMap.get(v));
return ans;
}
```
Expand Down
Loading