diff --git a/solution/3500-3599/3588.Find Maximum Area of a Triangle/README.md b/solution/3500-3599/3588.Find Maximum Area of a Triangle/README.md index da60079578fa2..de1091eea5c0e 100644 --- a/solution/3500-3599/3588.Find Maximum Area of a Triangle/README.md +++ b/solution/3500-3599/3588.Find Maximum Area of a Triangle/README.md @@ -75,32 +75,212 @@ tags: -### 方法一 +### 方法一:枚举 + 哈希表 + +题目要求三角形的两倍面积,因此我们可以直接计算三角形的底边和高的乘积。 + +又因为三角形至少有一条边与 $x$ 轴或 $y$ 轴平行,我们可以枚举与 $x$ 轴平行的边,计算所有可能的三角形的两倍面积,然后将 $\textit{coords}$ 横纵坐标交换后,重复上述过程,计算与 $y$ 轴平行的边的所有可能的三角形的两倍面积。 + +因此,我们设计一个函数 $\textit{calc}$ 来计算与 $y$轴平行的边的所有可能的三角形的两倍面积。 + +我们用两个哈希表 $\textit{f}$ 和 $\textit{g}$ 来记录每个横坐标对应的最小纵坐标和最大纵坐标。然后我们遍历 $\textit{coords}$,更新哈希表 $\textit{f}$ 和 $\textit{g}$,同时记录横坐标的最小值和最大值。最后,我们遍历哈希表 $\textit{f}$,计算每个横坐标对应的三角形的两倍面积,并更新答案。 + +在主函数中,我们先调用 $\textit{calc}$ 函数计算与 $y$ 轴平行的边的所有可能的三角形的两倍面积,然后将 $\textit{coords}$ 横纵坐标交换后,重复上述过程,计算与 $x$ 轴平行的边的所有可能的三角形的两倍面积。最后返回答案,如果答案为 0,则返回 -1。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是 $\textit{coords}$ 的长度。 #### Python3 ```python - +class Solution: + def maxArea(self, coords: List[List[int]]) -> int: + def calc() -> int: + mn, mx = inf, 0 + f = {} + g = {} + for x, y in coords: + mn = min(mn, x) + mx = max(mx, x) + if x in f: + f[x] = min(f[x], y) + g[x] = max(g[x], y) + else: + f[x] = g[x] = y + ans = 0 + for x, y in f.items(): + d = g[x] - y + ans = max(ans, d * max(mx - x, x - mn)) + return ans + + ans = calc() + for c in coords: + c[0], c[1] = c[1], c[0] + ans = max(ans, calc()) + return ans if ans else -1 ``` #### Java ```java - +class Solution { + public long maxArea(int[][] coords) { + long ans = calc(coords); + for (int[] c : coords) { + int tmp = c[0]; + c[0] = c[1]; + c[1] = tmp; + } + ans = Math.max(ans, calc(coords)); + return ans > 0 ? ans : -1; + } + + private long calc(int[][] coords) { + int mn = Integer.MAX_VALUE, mx = 0; + Map f = new HashMap<>(); + Map g = new HashMap<>(); + + for (int[] c : coords) { + int x = c[0], y = c[1]; + mn = Math.min(mn, x); + mx = Math.max(mx, x); + if (f.containsKey(x)) { + f.put(x, Math.min(f.get(x), y)); + g.put(x, Math.max(g.get(x), y)); + } else { + f.put(x, y); + g.put(x, y); + } + } + + long ans = 0; + for (var e : f.entrySet()) { + int x = e.getKey(); + int y = e.getValue(); + int d = g.get(x) - y; + ans = Math.max(ans, (long) d * Math.max(mx - x, x - mn)); + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + long long maxArea(vector>& coords) { + auto calc = [&]() -> long long { + int mn = INT_MAX, mx = 0; + unordered_map f, g; + for (auto& c : coords) { + int x = c[0], y = c[1]; + mn = min(mn, x); + mx = max(mx, x); + if (f.count(x)) { + f[x] = min(f[x], y); + g[x] = max(g[x], y); + } else { + f[x] = y; + g[x] = y; + } + } + long long ans = 0; + for (auto& [x, y] : f) { + int d = g[x] - y; + ans = max(ans, 1LL * d * max(mx - x, x - mn)); + } + return ans; + }; + + long long ans = calc(); + for (auto& c : coords) { + swap(c[0], c[1]); + } + ans = max(ans, calc()); + return ans > 0 ? ans : -1; + } +}; ``` #### Go ```go +func maxArea(coords [][]int) int64 { + calc := func() int64 { + mn, mx := int(1e9), 0 + f := make(map[int]int) + g := make(map[int]int) + for _, c := range coords { + x, y := c[0], c[1] + mn = min(mn, x) + mx = max(mx, x) + if _, ok := f[x]; ok { + f[x] = min(f[x], y) + g[x] = max(g[x], y) + } else { + f[x] = y + g[x] = y + } + } + var ans int64 + for x, y := range f { + d := g[x] - y + ans = max(ans, int64(d)*int64(max(mx-x, x-mn))) + } + return ans + } + + ans := calc() + for _, c := range coords { + c[0], c[1] = c[1], c[0] + } + ans = max(ans, calc()) + if ans > 0 { + return ans + } + return -1 +} +``` +#### TypeScript + +```ts +function maxArea(coords: number[][]): number { + function calc(): number { + let [mn, mx] = [Infinity, 0]; + const f = new Map(); + const g = new Map(); + + for (const [x, y] of coords) { + mn = Math.min(mn, x); + mx = Math.max(mx, x); + if (f.has(x)) { + f.set(x, Math.min(f.get(x)!, y)); + g.set(x, Math.max(g.get(x)!, y)); + } else { + f.set(x, y); + g.set(x, y); + } + } + + let ans = 0; + for (const [x, y] of f) { + const d = g.get(x)! - y; + ans = Math.max(ans, d * Math.max(mx - x, x - mn)); + } + return ans; + } + + let ans = calc(); + for (const c of coords) { + [c[0], c[1]] = [c[1], c[0]]; + } + ans = Math.max(ans, calc()); + return ans > 0 ? ans : -1; +} ``` diff --git a/solution/3500-3599/3588.Find Maximum Area of a Triangle/README_EN.md b/solution/3500-3599/3588.Find Maximum Area of a Triangle/README_EN.md index e5e427b5c02a7..78d5946463e22 100644 --- a/solution/3500-3599/3588.Find Maximum Area of a Triangle/README_EN.md +++ b/solution/3500-3599/3588.Find Maximum Area of a Triangle/README_EN.md @@ -73,32 +73,212 @@ tags: -### Solution 1 +### Solution 1: Enumeration + Hash Map + +The problem asks for twice the area of the triangle, so we can directly calculate the product of the base and height of the triangle. + +Since the triangle must have at least one side parallel to the $x$-axis or $y$-axis, we can enumerate sides parallel to the $x$-axis and calculate the double area for all possible triangles, then swap the coordinates in $\textit{coords}$ and repeat the process to calculate the double area for triangles with sides parallel to the $y$-axis. + +Therefore, we design a function $\textit{calc}$ to calculate the double area for all possible triangles with sides parallel to the $y$-axis. + +We use two hash maps $\textit{f}$ and $\textit{g}$ to record the minimum and maximum $y$-coordinates for each $x$-coordinate. Then we iterate through $\textit{coords}$, updating $\textit{f}$ and $\textit{g}$, and also record the minimum and maximum $x$-coordinates. Finally, we iterate through $\textit{f}$, calculate the double area for each $x$-coordinate, and update the answer. + +In the main function, we first call the $\textit{calc}$ function to calculate the double area for triangles with sides parallel to the $y$-axis, then swap the coordinates in $\textit{coords}$ and repeat the process to calculate the double area for triangles with sides parallel to the $x$-axis. Finally, we return the answer; if the answer is 0, we return -1. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of $\textit{coords}$. #### Python3 ```python - +class Solution: + def maxArea(self, coords: List[List[int]]) -> int: + def calc() -> int: + mn, mx = inf, 0 + f = {} + g = {} + for x, y in coords: + mn = min(mn, x) + mx = max(mx, x) + if x in f: + f[x] = min(f[x], y) + g[x] = max(g[x], y) + else: + f[x] = g[x] = y + ans = 0 + for x, y in f.items(): + d = g[x] - y + ans = max(ans, d * max(mx - x, x - mn)) + return ans + + ans = calc() + for c in coords: + c[0], c[1] = c[1], c[0] + ans = max(ans, calc()) + return ans if ans else -1 ``` #### Java ```java - +class Solution { + public long maxArea(int[][] coords) { + long ans = calc(coords); + for (int[] c : coords) { + int tmp = c[0]; + c[0] = c[1]; + c[1] = tmp; + } + ans = Math.max(ans, calc(coords)); + return ans > 0 ? ans : -1; + } + + private long calc(int[][] coords) { + int mn = Integer.MAX_VALUE, mx = 0; + Map f = new HashMap<>(); + Map g = new HashMap<>(); + + for (int[] c : coords) { + int x = c[0], y = c[1]; + mn = Math.min(mn, x); + mx = Math.max(mx, x); + if (f.containsKey(x)) { + f.put(x, Math.min(f.get(x), y)); + g.put(x, Math.max(g.get(x), y)); + } else { + f.put(x, y); + g.put(x, y); + } + } + + long ans = 0; + for (var e : f.entrySet()) { + int x = e.getKey(); + int y = e.getValue(); + int d = g.get(x) - y; + ans = Math.max(ans, (long) d * Math.max(mx - x, x - mn)); + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + long long maxArea(vector>& coords) { + auto calc = [&]() -> long long { + int mn = INT_MAX, mx = 0; + unordered_map f, g; + for (auto& c : coords) { + int x = c[0], y = c[1]; + mn = min(mn, x); + mx = max(mx, x); + if (f.count(x)) { + f[x] = min(f[x], y); + g[x] = max(g[x], y); + } else { + f[x] = y; + g[x] = y; + } + } + long long ans = 0; + for (auto& [x, y] : f) { + int d = g[x] - y; + ans = max(ans, 1LL * d * max(mx - x, x - mn)); + } + return ans; + }; + + long long ans = calc(); + for (auto& c : coords) { + swap(c[0], c[1]); + } + ans = max(ans, calc()); + return ans > 0 ? ans : -1; + } +}; ``` #### Go ```go +func maxArea(coords [][]int) int64 { + calc := func() int64 { + mn, mx := int(1e9), 0 + f := make(map[int]int) + g := make(map[int]int) + for _, c := range coords { + x, y := c[0], c[1] + mn = min(mn, x) + mx = max(mx, x) + if _, ok := f[x]; ok { + f[x] = min(f[x], y) + g[x] = max(g[x], y) + } else { + f[x] = y + g[x] = y + } + } + var ans int64 + for x, y := range f { + d := g[x] - y + ans = max(ans, int64(d)*int64(max(mx-x, x-mn))) + } + return ans + } + + ans := calc() + for _, c := range coords { + c[0], c[1] = c[1], c[0] + } + ans = max(ans, calc()) + if ans > 0 { + return ans + } + return -1 +} +``` +#### TypeScript + +```ts +function maxArea(coords: number[][]): number { + function calc(): number { + let [mn, mx] = [Infinity, 0]; + const f = new Map(); + const g = new Map(); + + for (const [x, y] of coords) { + mn = Math.min(mn, x); + mx = Math.max(mx, x); + if (f.has(x)) { + f.set(x, Math.min(f.get(x)!, y)); + g.set(x, Math.max(g.get(x)!, y)); + } else { + f.set(x, y); + g.set(x, y); + } + } + + let ans = 0; + for (const [x, y] of f) { + const d = g.get(x)! - y; + ans = Math.max(ans, d * Math.max(mx - x, x - mn)); + } + return ans; + } + + let ans = calc(); + for (const c of coords) { + [c[0], c[1]] = [c[1], c[0]]; + } + ans = Math.max(ans, calc()); + return ans > 0 ? ans : -1; +} ``` diff --git a/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.cpp b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.cpp new file mode 100644 index 0000000000000..bea1e1d87a8e6 --- /dev/null +++ b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.cpp @@ -0,0 +1,34 @@ +class Solution { +public: + long long maxArea(vector>& coords) { + auto calc = [&]() -> long long { + int mn = INT_MAX, mx = 0; + unordered_map f, g; + for (auto& c : coords) { + int x = c[0], y = c[1]; + mn = min(mn, x); + mx = max(mx, x); + if (f.count(x)) { + f[x] = min(f[x], y); + g[x] = max(g[x], y); + } else { + f[x] = y; + g[x] = y; + } + } + long long ans = 0; + for (auto& [x, y] : f) { + int d = g[x] - y; + ans = max(ans, 1LL * d * max(mx - x, x - mn)); + } + return ans; + }; + + long long ans = calc(); + for (auto& c : coords) { + swap(c[0], c[1]); + } + ans = max(ans, calc()); + return ans > 0 ? ans : -1; + } +}; diff --git a/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.go b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.go new file mode 100644 index 0000000000000..8064a77a7a0cd --- /dev/null +++ b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.go @@ -0,0 +1,35 @@ +func maxArea(coords [][]int) int64 { + calc := func() int64 { + mn, mx := int(1e9), 0 + f := make(map[int]int) + g := make(map[int]int) + for _, c := range coords { + x, y := c[0], c[1] + mn = min(mn, x) + mx = max(mx, x) + if _, ok := f[x]; ok { + f[x] = min(f[x], y) + g[x] = max(g[x], y) + } else { + f[x] = y + g[x] = y + } + } + var ans int64 + for x, y := range f { + d := g[x] - y + ans = max(ans, int64(d)*int64(max(mx-x, x-mn))) + } + return ans + } + + ans := calc() + for _, c := range coords { + c[0], c[1] = c[1], c[0] + } + ans = max(ans, calc()) + if ans > 0 { + return ans + } + return -1 +} diff --git a/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.java b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.java new file mode 100644 index 0000000000000..f61abadcf22f0 --- /dev/null +++ b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.java @@ -0,0 +1,40 @@ +class Solution { + public long maxArea(int[][] coords) { + long ans = calc(coords); + for (int[] c : coords) { + int tmp = c[0]; + c[0] = c[1]; + c[1] = tmp; + } + ans = Math.max(ans, calc(coords)); + return ans > 0 ? ans : -1; + } + + private long calc(int[][] coords) { + int mn = Integer.MAX_VALUE, mx = 0; + Map f = new HashMap<>(); + Map g = new HashMap<>(); + + for (int[] c : coords) { + int x = c[0], y = c[1]; + mn = Math.min(mn, x); + mx = Math.max(mx, x); + if (f.containsKey(x)) { + f.put(x, Math.min(f.get(x), y)); + g.put(x, Math.max(g.get(x), y)); + } else { + f.put(x, y); + g.put(x, y); + } + } + + long ans = 0; + for (var e : f.entrySet()) { + int x = e.getKey(); + int y = e.getValue(); + int d = g.get(x) - y; + ans = Math.max(ans, (long) d * Math.max(mx - x, x - mn)); + } + return ans; + } +} diff --git a/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.py b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.py new file mode 100644 index 0000000000000..4cdcb49614b00 --- /dev/null +++ b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.py @@ -0,0 +1,25 @@ +class Solution: + def maxArea(self, coords: List[List[int]]) -> int: + def calc() -> int: + mn, mx = inf, 0 + f = {} + g = {} + for x, y in coords: + mn = min(mn, x) + mx = max(mx, x) + if x in f: + f[x] = min(f[x], y) + g[x] = max(g[x], y) + else: + f[x] = g[x] = y + ans = 0 + for x, y in f.items(): + d = g[x] - y + ans = max(ans, d * max(mx - x, x - mn)) + return ans + + ans = calc() + for c in coords: + c[0], c[1] = c[1], c[0] + ans = max(ans, calc()) + return ans if ans else -1 diff --git a/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.ts b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.ts new file mode 100644 index 0000000000000..fa4cb72aa3b6f --- /dev/null +++ b/solution/3500-3599/3588.Find Maximum Area of a Triangle/Solution.ts @@ -0,0 +1,33 @@ +function maxArea(coords: number[][]): number { + function calc(): number { + let [mn, mx] = [Infinity, 0]; + const f = new Map(); + const g = new Map(); + + for (const [x, y] of coords) { + mn = Math.min(mn, x); + mx = Math.max(mx, x); + if (f.has(x)) { + f.set(x, Math.min(f.get(x)!, y)); + g.set(x, Math.max(g.get(x)!, y)); + } else { + f.set(x, y); + g.set(x, y); + } + } + + let ans = 0; + for (const [x, y] of f) { + const d = g.get(x)! - y; + ans = Math.max(ans, d * Math.max(mx - x, x - mn)); + } + return ans; + } + + let ans = calc(); + for (const c of coords) { + [c[0], c[1]] = [c[1], c[0]]; + } + ans = Math.max(ans, calc()); + return ans > 0 ? ans : -1; +}