Rectangle Area
- Easy
- tag: math, 几何
- 类似题目: 多边形分三角, max colinear, KD-tree...
Find the total area covered by two rectilinear rectangles in a 2D plane.
- 题目给出左下和右上的坐标.
思路
- 一开始先看题目, 看有什么性质. 大概的思路就是: 2个面积之和, 减去, 重叠部分的面积.
- 不过这4个点给出来要分的情况很多, 怎么做? 有什么简单的方法吗?
idea:
- 看一下草图: .
- 可以不用先分类, 而是直接写出"重叠部分"的点, 然后再分类即可(?)
- 如上图所示, 其中虚线部分即是overlap的部分.
- left = max(A,E)
- right = min(C,G)
- top = min(H,D)
- bottom = max(B,F)
写出点后, 再分类就很容易了: 要想overlap部分有效, 即需要:
right > left && top > bottom
. 这比起通过2个大矩形判断重叠部分要简单太多了!然后代码就很好写了, 这里参考的discuss的好解法.
public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
//if (A <= C && C <= B && B <= D || C <= A && A <= D && D <= B) {
// if (E <= G && G <= F && F <= H || G <= E && E <= H && H <= F) {
// return Math.abs() // 怎么分类???
// }
//}
int areaABCD = (C-A) * (D-B);
int areaEFGH = (G-E) * (H-F);
int left = Math.max(A,E);
int right = Math.min(C,G);
int top = Math.min(D,H);
int bottom = Math.max(B,F);
int ovlap = 0;
if (right > left && top > bottom) {
ovlap = (right - left) * (top - bottom);
}
return areaABCD + areaEFGH - ovlap;
}
写后感
- 这里的难点是怎么判断有没有overlap. 我一开始是正向思维: 即通过2个矩形的坐标来判断, 但是分类很多, 很容易错乱.
- 实际上应该像find median那样: 可以求一般情况: find Kth Largest (Quick select: O(N)), 然后就很容易做了.
- 同样, 这里直接先假设有overlap, 求出left/right/top/bottom. 然后就超级容易判断是否存在了.
- 这种通过直接求解, 再判断的思维方式很重要!
- 还有一开始我总是混淆row/col, 以及x/y. 搞的坐标错乱, 而且居然忘了坐标轴的方向了... 搞错了max还是min.