• 391. 完美矩形 扫描线


    391. 完美矩形

    难度困难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. 非法条件:开头重复/产生多个开头结尾/开头结尾和前面已出现行的开头结尾不一致

    1. class Solution {
    2. final int OPEN = 1;
    3. final int CLOSE = 0;
    4. public boolean isRectangleCover(int[][] rectangles) {
    5. int n = rectangles.length;
    6. int[][] sortLines = new int[n*2][4];
    7. for(int i = 0; i < n; i++){
    8. int[] rectangle=rectangles[i];
    9. int x1 = rectangle[0];
    10. int y1 = rectangle[1];
    11. int x2 = rectangle[2];
    12. int y2 = rectangle[3];
    13. sortLines[i*2] = new int[]{OPEN,y1,x1,x2};
    14. sortLines[i*2+1] = new int[]{CLOSE,y2,x1,x2};
    15. }
    16. Arrays.sort(sortLines,(a,b)->{
    17. if(a[1]!=b[1]) return a[1]-b[1];
    18. if(a[0]!=b[0]) return a[0]-b[0];
    19. return a[2]-b[2];
    20. });
    21. int startX = Integer.MIN_VALUE;
    22. int endX = Integer.MIN_VALUE;
    23. Set a = new HashSet<>();
    24. Set b = new HashSet<>();
    25. Map map = new HashMap<>();
    26. for(int i = 0; i < n*2; ){
    27. int y = sortLines[i][1];
    28. while (i2&&y==sortLines[i][1]){
    29. if(sortLines[i][0]==OPEN && map.containsKey(sortLines[i][2])) return false;
    30. int start = sortLines[i][2];
    31. int end = sortLines[i][3];
    32. if(sortLines[i][0]==OPEN){
    33. map.put(start,end);
    34. if(b.contains(start)) b.remove(start);
    35. else a.add(start);
    36. if(a.contains(end)) a.remove(end);
    37. else b.add(end);
    38. }else{
    39. map.remove(start);
    40. if(a.contains(start)) a.remove(start);
    41. else b.add(start);
    42. if(b.contains(end)) b.remove(end);
    43. else a.add(end);
    44. }
    45. ++i;
    46. }
    47. //检查x
    48. if(i2&&map.isEmpty()) return false;
    49. if(!map.isEmpty()){
    50. int min = Integer.MAX_VALUE;
    51. int max = Integer.MIN_VALUE;
    52. for(int key:a) min = key;
    53. for(int value:b) max = value;
    54. if(startX == Integer.MIN_VALUE){
    55. startX = min;
    56. endX = max;
    57. }
    58. if(startX != min || endX != max) return false;
    59. if(a.size()!=1||!a.contains(min)) return false;
    60. if(b.size()!=1||!b.contains(max)) return false;
    61. }
    62. }
    63. return true;
    64. }
    65. }

  • 相关阅读:
    在Windows中自动压缩备份文件和目录的脚本
    Docker容器-Consul部署
    智安网络|揭开云服务的神秘面纱:其含义和功能的综合指南
    什么是数据资产?数据资产管理应该如何落地?
    015 gtsam/examples/METISOrderingExample.cpp
    【微服务】Nacos初体验
    集合系列(十八) -List集合移除元素的坑点总结
    个人教学网站设计
    dm8 什么时候视图中统计的内存会超过OS
    在Windows上安装Docker与k8s,完美亲测!
  • 原文地址:https://blog.csdn.net/yu_duan_hun/article/details/126910710