diff --git a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README.md b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README.md index 56472db80a8b6..c708d7b27a77c 100644 --- a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README.md +++ b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README.md @@ -94,11 +94,15 @@ tags: -### 方法一:差分有序哈希表 +### 方法一:差分思想 + 哈希表 -我们利用差分思想,使用有序哈希表 `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$ 为建筑物数量。 @@ -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 ``` @@ -136,36 +141,34 @@ class Solution: ```java class Solution { public int[][] averageHeightOfBuildings(int[][] buildings) { - TreeMap height = new TreeMap<>(); - TreeMap 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 cnt = new HashMap<>(); + TreeMap 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 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 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][]); } } ``` @@ -176,27 +179,35 @@ class Solution { class Solution { public: vector> averageHeightOfBuildings(vector>& buildings) { - map 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 cnt; + map 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> ans; - int i = 0, h = 0, n = 0; - for (auto& [j, _] : cnt) { - if (n) { - vector 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; } }; @@ -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(); + const d = new Map(); + 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; +} +``` + diff --git a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README_EN.md b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README_EN.md index 3dd6827cdc451..cea37106ad1c6 100644 --- a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README_EN.md +++ b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/README_EN.md @@ -95,11 +95,15 @@ We cannot group the segments together because an empty space with no buildings s -### Solution 1: Differential Ordered Hash Table +### Solution 1: Difference Array + Hash Table -We use the differential idea and an ordered hash table `height` to record the height change at each position, and `cnt` to record the change in the number of buildings. By calculating the prefix sum of the ordered hash table, we can get the height and the number of buildings at each position. +We can use the difference array concept, utilizing a hash table $\textit{cnt}$ to record the change in the number of buildings at each position, and another hash table $\textit{d}$ to record the change in height at each position. -Finally, we traverse the ordered hash table. For each position, if both the height and the number of buildings are not zero, it means that there is a building at this position. We then check whether the average height of the building at this time is the same as that of the previous building. If it is the same, we merge them; otherwise, we add it to the result set. +Next, we sort the hash table $\textit{d}$ by its keys, use a variable $\textit{s}$ to record the current total height, and a variable $\textit{m}$ to record the current number of buildings. + +Then, we traverse the hash table $\textit{d}$. For each position, if $\textit{m}$ is not 0, it means there are buildings at the previous positions. We calculate the average height. If the average height of the buildings at the current position is the same as that of the previous buildings, we merge them; otherwise, we add the current position to the result set. + +Finally, we return the result set. The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the number of buildings. @@ -110,25 +114,26 @@ The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. ```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 ``` @@ -137,36 +142,34 @@ class Solution: ```java class Solution { public int[][] averageHeightOfBuildings(int[][] buildings) { - TreeMap height = new TreeMap<>(); - TreeMap 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 cnt = new HashMap<>(); + TreeMap 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 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 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][]); } } ``` @@ -177,27 +180,35 @@ class Solution { class Solution { public: vector> averageHeightOfBuildings(vector>& buildings) { - map 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 cnt; + map 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> ans; - int i = 0, h = 0, n = 0; - for (auto& [j, _] : cnt) { - if (n) { - vector 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; } }; @@ -207,39 +218,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(); + const d = new Map(); + 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; +} +``` + diff --git a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.cpp b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.cpp index 3a34325ab1ceb..6bfd728a7bbf7 100644 --- a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.cpp +++ b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.cpp @@ -1,27 +1,35 @@ class Solution { public: vector> averageHeightOfBuildings(vector>& buildings) { - map 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 cnt; + map 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> ans; - int i = 0, h = 0, n = 0; - for (auto& [j, _] : cnt) { - if (n) { - vector 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; } -}; \ No newline at end of file +}; diff --git a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.go b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.go index a781b304a795b..42d8ef6b7bbd1 100644 --- a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.go +++ b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.go @@ -1,32 +1,39 @@ 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 -} \ No newline at end of file +} diff --git a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.java b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.java index 92ce24df13842..f7ce7abf52ac7 100644 --- a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.java +++ b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.java @@ -1,34 +1,32 @@ class Solution { public int[][] averageHeightOfBuildings(int[][] buildings) { - TreeMap height = new TreeMap<>(); - TreeMap 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 cnt = new HashMap<>(); + TreeMap 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 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 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; + s += v; + m += cnt.get(k); + last = k; } - int[][] ans = new int[res.size()][3]; - for (i = 0; i < ans.length; ++i) { - ans[i] = res.get(i); - } - return ans; + return ans.toArray(new int[0][]); } -} \ No newline at end of file +} diff --git a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.py b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.py index 10afd336d6365..92f2d2613fa62 100644 --- a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.py +++ b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.py @@ -1,22 +1,23 @@ 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 diff --git a/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.ts b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.ts new file mode 100644 index 0000000000000..f15a6abb0f452 --- /dev/null +++ b/solution/2000-2099/2015.Average Height of Buildings in Each Segment/Solution.ts @@ -0,0 +1,29 @@ +function averageHeightOfBuildings(buildings: number[][]): number[][] { + const cnt = new Map(); + const d = new Map(); + 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; +} diff --git a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README.md b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README.md index 2071ad30aa074..3a79b01b00a73 100644 --- a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README.md +++ b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README.md @@ -67,9 +67,11 @@ tags: ### 方法一:维护前缀最小值 -我们用变量 $mi$ 表示当前遍历到的元素中的最小值,用变量 $ans$ 表示最大差值,初始时 $mi$ 为 $+\infty$,而 $ans$ 为 $-1$。 +我们用一个变量 $\textit{mi}$ 表示当前遍历到的元素中的最小值,用一个变量 $\textit{ans}$ 表示最大差值,初始时 $\textit{mi}$ 为 $+\infty$,而 $\textit{ans}$ 为 $-1$。 -遍历数组,对于当前遍历到的元素 $x$,如果 $x \gt mi$,则更新 $ans$ 为 $max(ans, x - mi)$,否则更新 $mi = x$。 +遍历数组,对于当前遍历到的元素 $x$,如果 $x \gt \textit{mi}$,则更新 $\textit{ans}$ 为 $\max(\textit{ans}, x - \textit{mi})$,否则更新 $\textit{mi} = x$。 + +遍历结束后,返回 $\textit{ans}$。 遍历结束后,返回 $ans$。 @@ -152,14 +154,15 @@ func maximumDifference(nums []int) int { ```ts function maximumDifference(nums: number[]): number { - const n = nums.length; - let min = nums[0]; - let res = -1; - for (let i = 1; i < n; i++) { - res = Math.max(res, nums[i] - min); - min = Math.min(min, nums[i]); + let [ans, mi] = [-1, Infinity]; + for (const x of nums) { + if (x > mi) { + ans = Math.max(ans, x - mi); + } else { + mi = x; + } } - return res === 0 ? -1 : res; + return ans; } ``` @@ -168,16 +171,18 @@ function maximumDifference(nums: number[]): number { ```rust impl Solution { pub fn maximum_difference(nums: Vec) -> i32 { - let mut min = nums[0]; - let mut res = -1; - for i in 1..nums.len() { - res = res.max(nums[i] - min); - min = min.min(nums[i]); - } - match res { - 0 => -1, - _ => res, + let mut mi = i32::MAX; + let mut ans = -1; + + for &x in &nums { + if x > mi { + ans = ans.max(x - mi); + } else { + mi = x; + } } + + ans } } ``` @@ -190,10 +195,9 @@ impl Solution { * @return {number} */ var maximumDifference = function (nums) { - let mi = 1 << 30; - let ans = -1; + let [ans, mi] = [-1, Infinity]; for (const x of nums) { - if (mi < x) { + if (x > mi) { ans = Math.max(ans, x - mi); } else { mi = x; diff --git a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README_EN.md b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README_EN.md index 6e674cdebac22..5bc56c0574bc9 100644 --- a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README_EN.md +++ b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/README_EN.md @@ -68,13 +68,13 @@ The maximum difference occurs with i = 0 and j = 3, nums[j] - nums[i] = 10 - 1 = ### Solution 1: Maintaining Prefix Minimum -We use the variable $mi$ to represent the minimum value of the elements we have traversed so far, and the variable $ans$ to represent the maximum difference. Initially, $mi$ is set to $+\infty$, and $ans$ is set to $-1$. +We use a variable $\textit{mi}$ to represent the minimum value among the elements currently being traversed, and a variable $\textit{ans}$ to represent the maximum difference. Initially, $\textit{mi}$ is set to $+\infty$, and $\textit{ans}$ is set to $-1$. -We traverse the array. For the current element $x$, if $x > mi$, then we update $ans$ to be $max(ans, x - mi)$, otherwise we update $mi = x$. +Traverse the array. For the current element $x$, if $x \gt \textit{mi}$, update $\textit{ans}$ to $\max(\textit{ans}, x - \textit{mi})$. Otherwise, update $\textit{mi}$ to $x$. -After the traversal, we return $ans$. +After the traversal, return $\textit{ans}$. -The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$. +Time complexity is $O(n)$, where $n$ is the length of the array. Space complexity is $O(1)$. @@ -153,14 +153,15 @@ func maximumDifference(nums []int) int { ```ts function maximumDifference(nums: number[]): number { - const n = nums.length; - let min = nums[0]; - let res = -1; - for (let i = 1; i < n; i++) { - res = Math.max(res, nums[i] - min); - min = Math.min(min, nums[i]); + let [ans, mi] = [-1, Infinity]; + for (const x of nums) { + if (x > mi) { + ans = Math.max(ans, x - mi); + } else { + mi = x; + } } - return res === 0 ? -1 : res; + return ans; } ``` @@ -169,16 +170,18 @@ function maximumDifference(nums: number[]): number { ```rust impl Solution { pub fn maximum_difference(nums: Vec) -> i32 { - let mut min = nums[0]; - let mut res = -1; - for i in 1..nums.len() { - res = res.max(nums[i] - min); - min = min.min(nums[i]); - } - match res { - 0 => -1, - _ => res, + let mut mi = i32::MAX; + let mut ans = -1; + + for &x in &nums { + if x > mi { + ans = ans.max(x - mi); + } else { + mi = x; + } } + + ans } } ``` @@ -191,10 +194,9 @@ impl Solution { * @return {number} */ var maximumDifference = function (nums) { - let mi = 1 << 30; - let ans = -1; + let [ans, mi] = [-1, Infinity]; for (const x of nums) { - if (mi < x) { + if (x > mi) { ans = Math.max(ans, x - mi); } else { mi = x; diff --git a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.js b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.js index b274f98f77620..b10ebb15e9573 100644 --- a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.js +++ b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.js @@ -3,10 +3,9 @@ * @return {number} */ var maximumDifference = function (nums) { - let mi = 1 << 30; - let ans = -1; + let [ans, mi] = [-1, Infinity]; for (const x of nums) { - if (mi < x) { + if (x > mi) { ans = Math.max(ans, x - mi); } else { mi = x; diff --git a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.rs b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.rs index a89640cfab55f..4e952543ff0fe 100644 --- a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.rs +++ b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.rs @@ -1,14 +1,16 @@ impl Solution { pub fn maximum_difference(nums: Vec) -> i32 { - let mut min = nums[0]; - let mut res = -1; - for i in 1..nums.len() { - res = res.max(nums[i] - min); - min = min.min(nums[i]); - } - match res { - 0 => -1, - _ => res, + let mut mi = i32::MAX; + let mut ans = -1; + + for &x in &nums { + if x > mi { + ans = ans.max(x - mi); + } else { + mi = x; + } } + + ans } } diff --git a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.ts b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.ts index 82f7d1c160a0e..9cb41459a4de6 100644 --- a/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.ts +++ b/solution/2000-2099/2016.Maximum Difference Between Increasing Elements/Solution.ts @@ -1,10 +1,11 @@ function maximumDifference(nums: number[]): number { - const n = nums.length; - let min = nums[0]; - let res = -1; - for (let i = 1; i < n; i++) { - res = Math.max(res, nums[i] - min); - min = Math.min(min, nums[i]); + let [ans, mi] = [-1, Infinity]; + for (const x of nums) { + if (x > mi) { + ans = Math.max(ans, x - mi); + } else { + mi = x; + } } - return res === 0 ? -1 : res; + return ans; }