100169. 移除栅栏得到的正方形田地的最大面积
有一个大型的 (m - 1) x (n - 1)
矩形田地,其两个对角分别是 (1, 1)
和 (m, n)
,田地内部有一些水平栅栏和垂直栅栏,分别由数组 hFences
和 vFences
给出。
水平栅栏为坐标 (hFences[i], 1)
到 (hFences[i], n)
,垂直栅栏为坐标 (1, vFences[i])
到 (m, vFences[i])
。
返回通过 移除 一些栅栏(可能不移除)所能形成的最大面积的 正方形 田地的面积,或者如果无法形成正方形田地则返回 -1
。
由于答案可能很大,所以请返回结果对 109 + 7
取余 后的值。
注意:田地外围两个水平栅栏(坐标 (1, 1)
到 (1, n)
和坐标 (m, 1)
到 (m, n)
)以及两个垂直栅栏(坐标 (1, 1)
到 (m, 1)
和坐标 (1, n)
到 (m, n)
)所包围。这些栅栏 不能 被移除。
示例 1:
输入:m = 4, n = 3, hFences = [2,3], vFences = [2] 输出:4 解释:移除位于 2 的水平栅栏和位于 2 的垂直栅栏将得到一个面积为 4 的正方形田地。
示例 2:
输入:m = 6, n = 7, hFences = [2], vFences = [4] 输出:-1 解释:可以证明无法通过移除栅栏形成正方形田地。
提示:
3 <= m, n <= 109
1 <= hFences.length, vFences.length <= 600
1 < hFences[i] < m
1 < vFences[i] < n
hFences
和 vFences
中的元素是唯一的。原站题解
golang 解法, 执行用时: 692 ms, 内存消耗: 20.1 MB, 提交时间: 2023-12-24 20:03:58
func f(a []int, mx int) (set map[int]bool) { a = append(a, 1, mx) slices.Sort(a) set = map[int]bool{} for i, x := range a { for _, y := range a[i+1:] { set[y-x] = true } } return } func maximizeSquareArea(m, n int, hFences, vFences []int) int { h := f(hFences, m) v := f(vFences, n) ans := 0 for x := range h { if v[x] { ans = max(ans, x) } } if ans == 0 { return -1 } return ans * ans % 1_000_000_007 }
cpp 解法, 执行用时: 2164 ms, 内存消耗: 431 MB, 提交时间: 2023-12-24 20:03:47
class Solution { unordered_set<int> f(vector<int> &a, int mx) { a.push_back(1); a.push_back(mx); sort(a.begin(), a.end()); unordered_set<int> set; for (int i = 0; i < a.size(); i++) { for (int j = i + 1; j < a.size(); j++) { set.insert(a[j] - a[i]); } } return set; } public: int maximizeSquareArea(int m, int n, vector<int> &hFences, vector<int> &vFences) { auto h = f(hFences, m); auto v = f(vFences, n); if (h.size() > v.size()) { swap(h, v); } int ans = 0; for (int x: h) { if (v.contains(x)) { ans = max(ans, x); } } return ans ? (long long) ans * ans % 1'000'000'007 : -1; } };
java 解法, 执行用时: 642 ms, 内存消耗: 85.6 MB, 提交时间: 2023-12-24 20:03:33
class Solution { public int maximizeSquareArea(int m, int n, int[] hFences, int[] vFences) { Set<Integer> h = f(hFences, m); Set<Integer> v = f(vFences, n); int ans = 0; for (int x : h) { if (v.contains(x)) { ans = Math.max(ans, x); } } return ans > 0 ? (int) ((long) ans * ans % 1_000_000_007) : -1; } private Set<Integer> f(int[] a, int mx) { int len = a.length; a = Arrays.copyOf(a, len + 2); a[len] = 1; a[len + 1] = mx; Arrays.sort(a); Set<Integer> set = new HashSet<>(); for (int i = 0; i < a.length; i++) { for (int j = i + 1; j < a.length; j++) { set.add(a[j] - a[i]); } } return set; } }
python3 解法, 执行用时: 1176 ms, 内存消耗: 54.5 MB, 提交时间: 2023-12-24 20:03:18
''' 水平栅栏和垂直栅栏分开计算。 对于水平栅栏,计算出任意两个栅栏之间的距离,存到一个哈希表 h 中。 对于垂直栅栏,计算出任意两个栅栏之间的距离,存到一个哈希表 v 中。 答案就是 h 和 v 交集中的最大值的平方。如果不存在最大值,返回 −1。 ''' class Solution: def maximizeSquareArea(self, m: int, n: int, hFences: List[int], vFences: List[int]) -> int: h = self.f(hFences, m) v = self.f(vFences, n) ans = max(h & v, default=0) return ans ** 2 % 1_000_000_007 if ans else -1 def f(self, a: List[int], mx: int) -> Set[int]: a.extend([1, mx]) a.sort() return set(y - x for x, y in combinations(a, 2))