题意为:给定在 xy 平面上的一组点,确定由这些点组成的任何矩形的最小面积,其中矩形的边不一定平行于 x 轴和 y 轴。
思路:找到各个矩形的几何方法。
原理:
(1)平行的定义:两个点(x1,y1),(x2,y2)的向量为(x1-x2,y1-y2),两条平行线的向量相等;
(2)垂直的定义:两个向量的点积为0,两个向量(x1,y1),(x2,y2),点积的为x1*x2+y1*y2;
(3)距离的公式为:两个点(x1,y1),(x2,y2),距离的平方为(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
(4)面积的公式为:长的距离x宽的距离;
代码如下:
class Solution {
public:
double minAreaFreeRect(vector<vector<int>>& p) {
int ps =p.size();
long mins=LONG_MAX;
unordered_map<string,vector<vector<long>>> mp;
for(int i=0;i<ps-1;i++)
{
long x1=p[i][0],y1=p[i][1];
//得到p1
for(int j=i+1;j<ps;j++)
{
long x2=p[j][0],y2=p[j][1];
//得到p2
long x=x1-x2;
long y=y1-y2;
if(x<0)//统一向量的方向
{
x=-x;
y=-y;
}
string key =to_string(x)+"#"+to_string(y);
if(mp.count(key) == 1)
{
for(int k=0;k<mp[key].size();k++)
{
long x3=mp[key][k][0],y3=mp[key][k][1],x4=mp[key][k][2],y4=mp[key][k][3];
//得到p3,p4
if(((x3-x1)*x+(y3-y1)*y) == 0 && ((x4-x2)*x+(y4-y2)*y) == 0)//防止对角线冒充边
{
mins=min(mins,((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1))*(x*x+y*y));
}else if(((x4-x1)*x+(y4-y1)*y) == 0 && ((x3-x2)*x+(y3-y2)*y) == 0)
{
mins=min(mins,((x4-x1)*(x4-x1)+(y4-y1)*(y4-y1))*(x*x+y*y));
}
}
}
vector<long> v(4,0);
v[0]=x1;v[1]=y1; v[2]=x2;v[3]=y2;
mp[key].push_back(v);//防止多个平行线,覆盖有用的信息
}
}
if(mins == LONG_MAX)
return 0;
return sqrt(mins);
}
};
代码中,用一个哈希表来存放各个向量,得到p1,p2,p3,p4后,求面积即可。