LeetCode - 939. Minimum Area Rectangle (C++)

LeetCode - 939. Minimum Area Rectangle

Given a set of points in the xy-plane, determine the minimum area of a rectangle formed from these points, with sides parallel to the x and y axes.

If there isn't any rectangle, return 0.

Example 1:

Input: [[1,1],[1,3],[3,1],[3,3],[2,2]]           Output: 4

Example 2:

Input: [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]]     Output: 2

Note:

  1. 1 <= points.length <= 500
  2. 0 <= points[i][0] <= 40000
  3. 0 <= points[i][1] <= 40000
  4. All points are distinct.

解:

    这道题目一开始的想法是,画很多条与坐标轴平行的线(比如 x = 5 出现过两次,那么 x = 5 这个位置就有一根线,用 40000 大小的两个数组就可以存储xy方向上的所有线), 算出所有平行线中xy方向上距离最短的四根,交叉出的区域就是最小的矩形,这样应该会很快。但是很快就想到了反例,如下图(许县区域会被当做最小矩形,但其实是构成不了矩形的):

    所以改用最直接的方法,就是将所有点,也就是所有 (x, y) 的组合存起来,之后,每两个点 (x1, y1), (x2, y2) 查找一次有没有 (x1, y2), (x2, y1) 两个点存在,这样就能构成一个矩形,计算面积,循环得到面积的最小值。将组合存起来最直接的想法就是 unordered_set<pair<int, int>>,但是这样 C++ 是不知道如何计算 pair 的 hash 值的,所以需要重载 () 操作符,比较麻烦,改用效率低一些的 set 即可,AC代码如下:

int minAreaRect(vector<vector<int>>& points) {
    bool found = false;
    int psize = points.size(), min_area = INT_MAX;
    set<pair<int, int>> setp;	// unordered_set会报错 "The C++ Standard doesn't provide a hash for this type."
    for (auto p : points)
        setp.insert(pair<int, int>(p[0], p[1]));
    for (int i = 0; i < psize; i++)
        for (int j = i + 1; j < psize; j++)
        {
            int x1 = points[i][0], y1 = points[i][1], x2 = points[j][0], y2 = points[j][1];
            if (x1 == x2 || y1 == y2) continue;
            if (abs(x1 - x2) * abs(y1 - y2) >= min_area) continue;	// 一定不是最小矩形
            if (setp.find(pair<int, int>(x1, y2)) != setp.end()
             && setp.find(pair<int, int>(x2, y1)) != setp.end())	// 另两个点存在
            {
                found = true;
                min_area = min(min_area, abs(x1 - x2) * abs(y1 - y2));
            }
        }
    if (found == false) return 0;
    return min_area;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值