3394. 判断网格图能否被切割成块
给你一个整数 n
表示一个 n x n
的网格图,坐标原点是这个网格图的左下角。同时给你一个二维坐标数组 rectangles
,其中 rectangles[i]
的格式为 [startx, starty, endx, endy]
,表示网格图中的一个矩形。每个矩形定义如下:
(startx, starty)
:矩形的左下角。(endx, endy)
:矩形的右上角。注意 ,矩形相互之间不会重叠。你的任务是判断是否能找到两条 要么都垂直要么都水平 的 两条切割线 ,满足:
如果可以得到这样的切割,请你返回 true
,否则返回 false
。
示例 1:
输入:n = 5, rectangles = [[1,0,5,2],[0,2,2,4],[3,2,5,3],[0,4,4,5]]
输出:true
解释:
网格图如上所示,我们可以在 y = 2
和 y = 4
处进行水平切割,所以返回 true 。
示例 2:
输入:n = 4, rectangles = [[0,0,1,1],[2,0,3,4],[0,2,2,3],[3,0,4,3]]
输出:true
解释:
我们可以在 x = 2
和 x = 3
处进行竖直切割,所以返回 true 。
示例 3:
输入:n = 4, rectangles = [[0,2,2,4],[1,0,3,2],[2,2,3,4],[3,0,4,2],[3,2,4,4]]
输出:false
解释:
我们无法进行任何两条水平或者两条竖直切割并且满足题目要求,所以返回 false 。
提示:
3 <= n <= 109
3 <= rectangles.length <= 105
0 <= rectangles[i][0] < rectangles[i][2] <= n
0 <= rectangles[i][1] < rectangles[i][3] <= n
原站题解
python3 解法, 执行用时: 217 ms, 内存消耗: 81.6 MB, 提交时间: 2024-12-25 17:45:07
class Solution: def check(self, intervals: List[Tuple[int, int]]) -> bool: intervals.sort(key=lambda p: p[0]) # 按照左端点从小到大排序 cnt = max_r = 0 for l, r in intervals: if l >= max_r: # 新区间 cnt += 1 if r > max_r: max_r = r # 更新右端点最大值(手写 if 效率更高) return cnt >= 3 # 也可以在循环中提前退出,但是慢一些 def checkValidCuts(self, _: int, rectangles: List[List[int]]) -> bool: return self.check([(sx, ex) for sx, _, ex, _ in rectangles]) or \ self.check([(sy, ey) for _, sy, _, ey in rectangles])
golang 解法, 执行用时: 68 ms, 内存消耗: 21.1 MB, 提交时间: 2024-12-25 17:44:35
type pair struct{ l, r int } func check(intervals []pair) bool { // 按照左端点从小到大排序 slices.SortFunc(intervals, func(a, b pair) int { return a.l - b.l }) cnt, maxR := 0, 0 for _, p := range intervals { if p.l >= maxR { // 新区间 cnt++ } maxR = max(maxR, p.r) // 更新右端点最大值 } return cnt >= 3 // 也可以在循环中提前退出 } func checkValidCuts(_ int, rectangles [][]int) bool { a := make([]pair, len(rectangles)) b := make([]pair, len(rectangles)) for i, rect := range rectangles { a[i] = pair{rect[0], rect[2]} b[i] = pair{rect[1], rect[3]} } return check(a) || check(b) }
cpp 解法, 执行用时: 52 ms, 内存消耗: 201.3 MB, 提交时间: 2024-12-25 17:44:22
class Solution { public: bool check(vector<pair<int, int>>& intervals) { ranges::sort(intervals, {}, [](auto& a) { return a.first; });// 按照左端点从小到大排序 int cnt = 0, max_r = 0; for (auto& [l, r] : intervals) { if (l >= max_r) { // 新区间 cnt++; } max_r = max(max_r, r); // 更新右端点最大值 } return cnt >= 3; // 也可以在循环中提前退出 } bool checkValidCuts(int, vector<vector<int>>& rectangles) { vector<pair<int, int>> a, b; for (auto& rect : rectangles) { a.emplace_back(rect[0], rect[2]); b.emplace_back(rect[1], rect[3]); } return check(a) || check(b); } };
java 解法, 执行用时: 104 ms, 内存消耗: 119.7 MB, 提交时间: 2024-12-25 17:44:09
// 合并区间 class Solution { boolean checkValidCuts(int n, int[][] rectangles) { int m = rectangles.length; int[][] a = new int[m][2]; int[][] b = new int[m][2]; for (int i = 0; i < m; i++) { int[] rect = rectangles[i]; a[i][0] = rect[0]; a[i][1] = rect[2]; b[i][0] = rect[1]; b[i][1] = rect[3]; } return check(a) || check(b); } private boolean check(int[][] intervals) { Arrays.sort(intervals, (a, b) -> a[0] - b[0]); // 按照左端点从小到大排序 int cnt = 0; int maxR = 0; for (int[] interval : intervals) { if (interval[0] >= maxR) { // 新区间 cnt++; } maxR = Math.max(maxR, interval[1]); // 更新右端点最大值 } return cnt >= 3; // 也可以在循环中提前退出 } }