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.
這道題給了我們一堆點的坐標,問能組成的最小的矩形面積是多少,題目中限定了矩形的邊一定是平行於主軸的,不會出現旋轉矩形的形狀。如果知道了矩形的兩個對角頂點坐標,求面積就非常的簡單了,但是隨便取四個點並不能保證一定是矩形,不過這四個點坐標之間是有聯系的,相鄰的兩個頂點要么橫坐標,要么縱坐標,一定有一個是相等的,這個特點先記下。策略是,先找出兩個對角線的頂點,一但兩個對角頂點確定了,其實這個矩形的大小也就確定了,另外的兩個點其實就是分別在跟這兩個點具有相同的橫坐標或縱坐標的點中尋找即可,為了優化查找的時間,可以事先把所有具有相同橫坐標的點的縱坐標放入到一個 HashSet 中,使用一個 HashMap,建立橫坐標和所有具有該橫坐標的點的縱坐標的集合之間的映射。然后開始遍歷任意兩個點的組合,由於這兩個點必須是對角頂點,所以其橫縱坐標均不能相等,若有一個相等了,則跳過該組合。否則看其中任意一個點的橫坐標對應的集合中是否均包含另一個點的縱坐標,均包含的話,說明另兩個頂點也是存在的,就可以計算矩形的面積了,更新結果 res,若最終 res 還是初始值,說明並沒有能組成矩形,返回0即可,參見代碼如下:
class Solution {
public:
int minAreaRect(vector<vector<int>>& points) {
int res = INT_MAX, n = points.size();
unordered_map<int, unordered_set<int>> m;
for (auto point : points) {
m[point[0]].insert(point[1]);
}
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (points[i][0] == points[j][0] || points[i][1] == points[j][1]) continue;
if (m[points[i][0]].count(points[j][1]) && m[points[j][0]].count(points[i][1])) {
res = min(res, abs(points[i][0] - points[j][0]) * abs(points[i][1] - points[j][1]));
}
}
}
return res == INT_MAX ? 0 : res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/939
參考資料:
https://leetcode.com/problems/minimum-area-rectangle/
https://leetcode.com/problems/minimum-area-rectangle/discuss/192025/Java-N2-Hashmap
[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)