Skip to content

feat: add solutions to lc problems: No.2015,2016 #3370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 6, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,15 @@ tags:

<!-- solution:start -->

### 方法一:差分有序哈希表
### 方法一:差分思想 + 哈希表

我们利用差分思想,使用有序哈希表 `height` 记录每个位置的高度变化,`cnt` 记录建筑物的数量变化。对有序哈希表求前缀和,即可得到每个位置的高度和建筑物数量
我们可以利用差分思想,用一个哈希表 $\textit{cnt}$ 记录每个位置的建筑物数量变化,用另一个哈希表 $\textit{d}$ 记录每个位置的高度变化

最后遍历有序哈希表,对于每个位置,如果高度和建筑物数量都不为 0,则说明该位置有建筑物,判断此时的建筑物是否与上个建筑物的平均高度相同,如果相同,则合并,否则加入结果集。
接下来,我们对哈希表 $\textit{d}$ 按照键值进行排序,用一个变量 $\textit{s}$ 记录当前位置的高度和,用一个变量 $\textit{m}$ 记录当前位置的建筑物数量。

然后遍历哈希表 $\textit{d}$,对于每个位置,如果 $\textit{m}$ 不为 0,说明此前有建筑物,我们计算出平均高度,如果当前位置的建筑物与上个建筑物的平均高度相同,则合并,否则加入结果集。

最后返回结果集即可。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为建筑物数量。

Expand All @@ -109,25 +113,26 @@ tags:
```python
class Solution:
def averageHeightOfBuildings(self, buildings: List[List[int]]) -> List[List[int]]:
height = defaultdict(int)
cnt = defaultdict(int)
for s, e, h in buildings:
cnt[s] += 1
cnt[e] -= 1
height[s] += h
height[e] -= h
d = defaultdict(int)
for start, end, height in buildings:
cnt[start] += 1
cnt[end] -= 1
d[start] += height
d[end] -= height
s = m = 0
last = -1
ans = []
i = h = n = 0
for j in sorted(cnt.keys()):
if n:
t = [i, j, h // n]
if ans and ans[-1][1] == i and ans[-1][2] == t[-1]:
ans[-1][1] = j
for k, v in sorted(d.items()):
if m:
avg = s // m
if ans and ans[-1][2] == avg and ans[-1][1] == last:
ans[-1][1] = k
else:
ans.append(t)
i = j
h += height[j]
n += cnt[j]
ans.append([last, k, avg])
s += v
m += cnt[k]
last = k
return ans
```

Expand All @@ -136,36 +141,34 @@ class Solution:
```java
class Solution {
public int[][] averageHeightOfBuildings(int[][] buildings) {
TreeMap<Integer, Integer> height = new TreeMap<>();
TreeMap<Integer, Integer> cnt = new TreeMap<>();
for (var v : buildings) {
int s = v[0], e = v[1], h = v[2];
cnt.put(s, cnt.getOrDefault(s, 0) + 1);
cnt.put(e, cnt.getOrDefault(e, 0) - 1);
height.put(s, height.getOrDefault(s, 0) + h);
height.put(e, height.getOrDefault(e, 0) - h);
Map<Integer, Integer> cnt = new HashMap<>();
TreeMap<Integer, Integer> d = new TreeMap<>();
for (var e : buildings) {
int start = e[0], end = e[1], height = e[2];
cnt.merge(start, 1, Integer::sum);
cnt.merge(end, -1, Integer::sum);
d.merge(start, height, Integer::sum);
d.merge(end, -height, Integer::sum);
}
int i = 0, h = 0, n = 0;
List<int[]> res = new ArrayList<>();
for (int j : cnt.keySet()) {
if (n > 0) {
int[] t = new int[] {i, j, h / n};
int k = res.size() - 1;
if (k >= 0 && res.get(k)[1] == i && res.get(k)[2] == t[2]) {
res.get(k)[1] = j;
int s = 0, m = 0;
int last = -1;
List<int[]> ans = new ArrayList<>();
for (var e : d.entrySet()) {
int k = e.getKey(), v = e.getValue();
if (m > 0) {
int avg = s / m;
if (!ans.isEmpty() && ans.get(ans.size() - 1)[2] == avg
&& ans.get(ans.size() - 1)[1] == last) {
ans.get(ans.size() - 1)[1] = k;
} else {
res.add(t);
ans.add(new int[] {last, k, avg});
}
}
h += height.get(j);
n += cnt.get(j);
i = j;
}
int[][] ans = new int[res.size()][3];
for (i = 0; i < ans.length; ++i) {
ans[i] = res.get(i);
s += v;
m += cnt.get(k);
last = k;
}
return ans;
return ans.toArray(new int[0][]);
}
}
```
Expand All @@ -176,27 +179,35 @@ class Solution {
class Solution {
public:
vector<vector<int>> averageHeightOfBuildings(vector<vector<int>>& buildings) {
map<int, int> height, cnt;
for (auto& v : buildings) {
int s = v[0], e = v[1], h = v[2];
cnt[s]++, cnt[e]--;
height[s] += h, height[e] -= h;
unordered_map<int, int> cnt;
map<int, int> d;

for (const auto& e : buildings) {
int start = e[0], end = e[1], height = e[2];
cnt[start]++;
cnt[end]--;
d[start] += height;
d[end] -= height;
}

int s = 0, m = 0;
int last = -1;
vector<vector<int>> ans;
int i = 0, h = 0, n = 0;
for (auto& [j, _] : cnt) {
if (n) {
vector<int> t = {i, j, h / n};
if (ans.size() && ans.back()[1] == i && ans.back()[2] == t[2]) {
ans.back()[1] = j;

for (const auto& [k, v] : d) {
if (m > 0) {
int avg = s / m;
if (!ans.empty() && ans.back()[2] == avg && ans.back()[1] == last) {
ans.back()[1] = k;
} else {
ans.push_back(t);
ans.push_back({last, k, avg});
}
}
i = j;
h += height[j];
n += cnt[j];
s += v;
m += cnt[k];
last = k;
}

return ans;
}
};
Expand All @@ -206,39 +217,80 @@ public:

```go
func averageHeightOfBuildings(buildings [][]int) [][]int {
height := make(map[int]int)
cnt := make(map[int]int)
for _, v := range buildings {
s, e, h := v[0], v[1], v[2]
cnt[s]++
cnt[e]--
height[s] += h
height[e] -= h
d := make(map[int]int)

for _, e := range buildings {
start, end, height := e[0], e[1], e[2]
cnt[start]++
cnt[end]--
d[start] += height
d[end] -= height
}
keys := make([]int, len(cnt))
for k := range cnt {

s, m := 0, 0
last := -1
var ans [][]int

keys := make([]int, 0, len(d))
for k := range d {
keys = append(keys, k)
}
sort.Ints(keys)
i, h, n := 0, 0, 0
ans := [][]int{}
for _, j := range keys {
if n > 0 {
t := []int{i, j, h / n}
if len(ans) > 0 && ans[len(ans)-1][1] == i && ans[len(ans)-1][2] == t[2] {
ans[len(ans)-1][1] = j

for _, k := range keys {
v := d[k]
if m > 0 {
avg := s / m
if len(ans) > 0 && ans[len(ans)-1][2] == avg && ans[len(ans)-1][1] == last {
ans[len(ans)-1][1] = k
} else {
ans = append(ans, t)
ans = append(ans, []int{last, k, avg})
}
}
i = j
h += height[j]
n += cnt[j]
s += v
m += cnt[k]
last = k
}

return ans
}
```

#### TypeScript

```ts
function averageHeightOfBuildings(buildings: number[][]): number[][] {
const cnt = new Map<number, number>();
const d = new Map<number, number>();
for (const [start, end, height] of buildings) {
cnt.set(start, (cnt.get(start) || 0) + 1);
cnt.set(end, (cnt.get(end) || 0) - 1);
d.set(start, (d.get(start) || 0) + height);
d.set(end, (d.get(end) || 0) - height);
}
let [s, m] = [0, 0];
let last = -1;
const ans: number[][] = [];
const sortedKeys = Array.from(d.keys()).sort((a, b) => a - b);
for (const k of sortedKeys) {
const v = d.get(k)!;
if (m > 0) {
const avg = Math.floor(s / m);
if (ans.length > 0 && ans.at(-1)![2] === avg && ans.at(-1)![1] === last) {
ans[ans.length - 1][1] = k;
} else {
ans.push([last, k, avg]);
}
}
s += v;
m += cnt.get(k)!;
last = k;
}
return ans;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Loading
Loading