LeetcodeOJ 391 :Perfect Rectangle

题目地址:https://leetcode.com/problems/perfect-rectangle/description/

Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover of a rectangular region.

Each rectangle is represented as a bottom-left point and a top-right point. For example, a unit square is represented as [1,1,2,2]. (coordinate of bottom-left point is (1, 1) and top-right point is (2, 2)).

Example 1:

rectangles = [
  [1,1,3,3],
  [3,1,4,2],
  [3,2,4,4],
  [1,3,2,4],
  [2,3,3,4]
]

Return true. All 5 rectangles together form an exact cover of a rectangular region.

Example 2:

rectangles = [
  [1,1,2,3],
  [1,3,2,4],
  [3,1,4,2],
  [3,2,4,4]
]

Return false. Because there is a gap between the two rectangular regions.

Example 3:

rectangles = [
  [1,1,3,3],
  [3,1,4,2],
  [1,3,2,4],
  [3,2,4,4]
]

Return false. Because there is a gap in the top center.

Example 4:

rectangles = [
  [1,1,3,3],
  [3,1,4,2],
  [1,3,2,4],
  [2,2,4,4]
]

Return false. Because two of the rectangles overlap with each other.




开始的想法是建立一个board格子,记录哪些格子会被矩形覆盖且只覆盖一次,同时记录生成大矩形的左下角和右上角的坐标,计算小矩形面积之和与最后的大矩形面积是否相等。该方法在数据较大的时候会超时.

代码如下:

class Solution {
    public boolean isRectangleCover(int[][] rectangles) {
		int down = Integer.MAX_VALUE;
		int left = Integer.MAX_VALUE;
		int up = Integer.MIN_VALUE;
		int right = Integer.MIN_VALUE;
		for(int[] item : rectangles) {
			left = Math.min(left, item[0]);
			down = Math.min(down, item[1]);
			right = Math.max(right, item[2]);
			up = Math.max(up, item[3]);
		}
		
		int MAX = Math.max(up, right);
		int MIN = Math.min(down, left);
		int[][] board = new int[MAX+1-MIN][MAX+1-MIN];
		for(int[] item : rectangles) {
			for(int i = item[0]-MIN; i < item[2]-MIN; ++i) {
				for(int j = item[1]-MIN; j < item[3]-MIN; ++j) {
					if(board[i][j] == 1)
						return false;
					board[i][j] = 1;
				}
			}
		}
		
		for(int i = left-MIN; i < right-MIN; ++i) {
			for(int j = down-MIN; j < up-MIN; ++j) {
				if(board[i][j] != 1)
					return false;
			}
		}
		
		return true;
    }
}


改进方法核心思想是:能够正好围成一个矩形的情况就是: 

1. 最左下 最左上 最右下 最右上 的四个点只出现过一次,其他肯定是成对出现的(保证完全覆盖) 
2. 上面四个点围成的面积,正好等于所有子矩形的面积之和(保证不重复)

代码如下:

class Solution {
    public boolean isRectangleCover(int[][] rectangles) {
        int down = Integer.MAX_VALUE;
		int left = Integer.MAX_VALUE;
		int up = Integer.MIN_VALUE;
		int right = Integer.MIN_VALUE;
		int sum = 0; // 面积
		
		Set<String> set = new HashSet<>();
		for(int[] item : rectangles) {
			//四个顶点坐标
			String s1 = item[0] + " " + item[1];
			String s2 = item[2] + " " + item[3];
			String s3 = item[0] + " " + item[3];
			String s4 = item[2] + " " + item[1];
			if(set.contains(s1)) 
				set.remove(s1);			
			else
				set.add(s1);
			
			if(set.contains(s2)) 
				set.remove(s2);			
			else
				set.add(s2);
			
			if(set.contains(s3)) 
				set.remove(s3);			
			else
				set.add(s3);
			
			if(set.contains(s4)) 
				set.remove(s4);			
			else
				set.add(s4);
			
			down = Math.min(down, item[1]);
			left = Math.min(left, item[0]);
			up = Math.max(up, item[3]);
			right = Math.max(right, item[2]);
			sum += (item[3]-item[1]) * (item[2]-item[0]);
			
		}
		
		
		int area = (up-down) * (right-left);
		if(area != sum || set.size() != 4 || !set.contains(left+" "+down) || !set.contains(left+" "+up) || !set.contains(right+" "+down) || !set.contains(right+" "+up))
			return false;
		
		return true;
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值