难度困难234
给你一个数组
rectangles
,其中rectangles[i] = [xi, yi, ai, bi]
表示一个坐标轴平行的矩形。这个矩形的左下顶点是(xi, yi)
,右上顶点是(ai, bi)
。如果所有矩形一起精确覆盖了某个矩形区域,则返回
true
;否则,返回false
。示例 1:
输入:rectangles = [[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]] 输出:true 解释:5 个矩形一起可以精确地覆盖一个矩形区域。示例 2:
输入:rectangles = [[1,1,2,3],[1,3,2,4],[3,1,4,2],[3,2,4,4]] 输出:false 解释:两个矩形之间有间隔,无法覆盖成一个矩形。示例 3:
输入:rectangles = [[1,1,3,3],[3,1,4,2],[1,3,2,4],[2,2,4,4]] 输出:false 解释:因为中间有相交区域,虽然形成了矩形,但不是精确覆盖。提示:
1 <= rectangles.length <= 2 * 1e4
rectangles[i].length == 4
-105 <= xi, yi, ai, bi <= 1e5
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/perfect-rectangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
成功,写出扫描线方式,但是不太熟练
1. 按行扫描,按y排序,同行的先处理结束行,再处理开始行
2. 结束行:删掉头尾:如果有任何线以当前开头结尾则产生新的结尾,加到b,否则和当前已产生的结尾抵消;如果任何线以当前结尾开头则产生新的开头,添加到a,否则和当前产生的开头抵消。当前开头从去重哈希中移除
3. 开始行:添加开头不能产生重复。当前的开头结尾不断链接,最终会产生唯一的开头和唯一的结尾。如果第一次拿到开头结尾,则记录,否则判断是否相同开头结尾,是否唯一
4. 非法条件:开头重复/产生多个开头结尾/开头结尾和前面已出现行的开头结尾不一致
- class Solution {
- final int OPEN = 1;
- final int CLOSE = 0;
- public boolean isRectangleCover(int[][] rectangles) {
- int n = rectangles.length;
- int[][] sortLines = new int[n*2][4];
- for(int i = 0; i < n; i++){
- int[] rectangle=rectangles[i];
- int x1 = rectangle[0];
- int y1 = rectangle[1];
- int x2 = rectangle[2];
- int y2 = rectangle[3];
- sortLines[i*2] = new int[]{OPEN,y1,x1,x2};
- sortLines[i*2+1] = new int[]{CLOSE,y2,x1,x2};
- }
-
- Arrays.sort(sortLines,(a,b)->{
- if(a[1]!=b[1]) return a[1]-b[1];
- if(a[0]!=b[0]) return a[0]-b[0];
- return a[2]-b[2];
- });
- int startX = Integer.MIN_VALUE;
- int endX = Integer.MIN_VALUE;
- Set
a = new HashSet<>(); - Set
b = new HashSet<>(); - Map
map = new HashMap<>(); - for(int i = 0; i < n*2; ){
- int y = sortLines[i][1];
- while (i
2&&y==sortLines[i][1]){ - if(sortLines[i][0]==OPEN && map.containsKey(sortLines[i][2])) return false;
- int start = sortLines[i][2];
- int end = sortLines[i][3];
- if(sortLines[i][0]==OPEN){
- map.put(start,end);
- if(b.contains(start)) b.remove(start);
- else a.add(start);
- if(a.contains(end)) a.remove(end);
- else b.add(end);
- }else{
- map.remove(start);
- if(a.contains(start)) a.remove(start);
- else b.add(start);
-
- if(b.contains(end)) b.remove(end);
- else a.add(end);
- }
-
- ++i;
- }
- //检查x
- if(i
2&&map.isEmpty()) return false; - if(!map.isEmpty()){
- int min = Integer.MAX_VALUE;
- int max = Integer.MIN_VALUE;
- for(int key:a) min = key;
- for(int value:b) max = value;
-
- if(startX == Integer.MIN_VALUE){
- startX = min;
- endX = max;
- }
-
- if(startX != min || endX != max) return false;
- if(a.size()!=1||!a.contains(min)) return false;
- if(b.size()!=1||!b.contains(max)) return false;
- }
- }
- return true;
- }
- }