https://leetcode.com/problems/minimum-area-rectangle/
Input: [[1,1],[1,3],[3,1],[3,3],[2,2]]
Output: 4
Input: [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]]
Output: 2
가능한 사각형의 최소 크기를 구한다.
hash 안에 set을 넣어서 x 좌표는 hash의 key값으로, y좌표는 set으로 관리한다.
왼쪽 아래 모서리를 가지고 (outer for문) 오른쪽 위(inner for문) 모서리를 찾는다.
오른쪽 위 모서리는 왼쪽 아래보다 항상 커야 할 것이기 때문에 조건으로 잡았다.
그리고 난뒤 (1,1) (3,3)을 찾았다면, 사각형을 만들 수 있는 조건이 완성된다.
왼쪽 위 모서리는 (1,1) 에서 x좌표 1을 가져오고 (3,3) 에서 y좌표를 가져온다. (1, 3)
오른쪽 아래 모서리는 (1,1) 에서 y좌표 1을 가져오고 (3,3)에서 x좌표를 가져온다. (3, 1)
(1,3) 과 (3,1) 이 hash key값과, set의 key값으로 존재한다면 사각형이 완성된다.
이를 구해서 최소 값을 return 시켜주면 된다.
class Solution {
public:
int minAreaRect(vector<vector<int>>& points) {
std::unordered_map<int, std::unordered_set<int>> umap;
int min = INT_MAX;
for (int i = 0; i < points.size(); ++i)
{
umap[points[i][0]].emplace(points[i][1]);
}
for (int i = 0; i < points.size(); ++i)
{
for (int j = 0; j < points.size(); ++j)
{
if (points[j][0] > points[i][0] && points[j][1] > points[i][1])
{
//왼쪽 위 모서리
int leftupfirst = points[i][0];
int leftupsecond = points[j][1];
//오른쪽 아래 모서리
int rightdownfirst = points[j][0];
int rightdownsecond = points[i][1];
if (umap.find(leftupfirst) != umap.end())
{
if (umap[leftupfirst].find(leftupsecond) != umap[leftupfirst].end())
{
if (umap.find(rightdownfirst) != umap.end())
{
if (umap[rightdownfirst].find(rightdownsecond) != umap[rightdownfirst].end())
{
int base = points[j][0] - points[i][0];
int height = points[j][1] - points[i][1];
min = std::min(min, base * height);
}
}
}
}
}
}
}
return min == INT_MAX? 0 : min;
}
};
time complexity 는 2중 for문으로 O(n^2) 다시 key값을 찾는 시간 O(1)으로 O(n^2) 이다.
space complexity hash에 n의 점을 저장 해야 해서 O(n)이다.