939. Minimum Area Rectangle (C++)
阿新 • • 發佈:2018-12-20
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 <= points.length <= 500
0 <= points[i][0] <= 40000
0 <= points[i][1] <= 40000
- 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; }