391. Perfect Rectangle

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.


Idea1:面积和相等,矩形两两不相交,O(N^2)

Idea2:面积和相等,所有矩形的四个角(除了最后合并成的大矩形的四个角之外),都应该出现偶数次,O(N)

摘自

https://discuss.leetcode.com/topic/56052/really-easy-understanding-solution-o-n-java


The right answer must satisfy two conditions:

  1. the large rectangle area should be equal to the sum of small rectangles
  2. count of all the points should be even, and that of all the four corner points should be one

public class Solution {
    public static boolean isRectangleCover(int[][] rectangles)
	{
		int len=rectangles.length;
		if(len<2)
			return true;
		
		int left=Integer.MAX_VALUE,buttom=Integer.MAX_VALUE,right=Integer.MIN_VALUE,top=Integer.MIN_VALUE;
		int sumArea=0;
		HashSet<String> hashset=new HashSet<>();
		
		
		for(int i=0;i<len;i++)
		{
			if(rectangles[i][0]<left||rectangles[i][0]==left&&rectangles[i][1]<buttom)
			{
				left=rectangles[i][0];
				buttom=rectangles[i][1];
			}
			if(rectangles[i][2]>right||rectangles[i][2]==right&&rectangles[i][3]>top)
			{
				right=rectangles[i][2];
				top=rectangles[i][3];
			}
			sumArea+=(rectangles[i][2]-rectangles[i][0])*(rectangles[i][3]-rectangles[i][1]);
			
			String[] strs={rectangles[i][0]+" "+rectangles[i][1],rectangles[i][0]+" "+rectangles[i][3],rectangles[i][2]+" "+rectangles[i][1],rectangles[i][2]+" "+rectangles[i][3]};
			for(String s :strs)
				if(hashset.contains(s))
					hashset.remove(s);
				else {
					hashset.add(s);
				}
		}
		
		if(sumArea!=(right-left)*(top-buttom))
			return false;
		
		if(!hashset.contains(left+" "+buttom)||!hashset.contains(left+" "+top)||!hashset.contains(right+" "+buttom)||!hashset.contains(right+" "+top)||hashset.size()!=4)
			return false;
		
		return true;
		
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值