每日LeetCode —— 593. 有效的正方形

421 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

题目描述

给定一个二维坐标中的四个点的坐标,判断给出的四个点是否能够形成一个正方形;

例1:输入:"[6987,-473] [6985,-473] [6986,-472] [6986,-474]"  输出:"true"

例2:输入:"[0,0] [1,1] [1,0] [1,1]"  输出:"false"

本题值得注意的地方

  • 所给出的四个点的坐标没有顺序
  • 所给出的四个点的坐标有可能是重复的
  • 坐标的数值范围-1e4 ~ 1e4

原题地址:593. 有效的正方形

解题思路

       题目中所给的四个点有可能出现重复的点,这里为了方便,使用了 map 标记各点用来判断是否重复。

1.png

       判断一个图形是否为正方形的方法有很多,这里选择用对角线是否相等且垂直的方法。若对角线相等但不垂直,那该图形一定不是正方形,例如图中2长方形或者等腰梯形等。若对角线只垂直不相等,那么该图形也一定不为正方形,例如图中3的菱形。

       该题所给的参数为 4 个vector,且点的顺序是随机的,为了方便处理,我们应该先对四个点进行一个从左到右的排序。排序完成后,两个对角线即为点 0 与点 3 以及点 1 与点 2 所连成的线。在判断对角线是否垂直,只需要判断图中 1 的四个三角形其中之一为直角三角形即可。

实现代码

class Solution {
public:
    bool validSquare(vector<int>& p1, vector<int>& p2, vector<int>& p3, vector<int>& p4) {
        // 将p1 ~ p4放入一个vector中,方便排序与遍历
        vector<vector<int>> p = {p1,p2,p3,p4};
        // 利用map来检查输入的点有无重复
        map<vector<int>,int> map;
        for(int i = 0;i < 4;i++) if(++map[p[i]] > 1) return false;
        // 按照各点的 x 坐标升序排序,当横坐标一样时,按照纵坐标升序排序
        sort(p.begin(),p.end(),[](const auto &a,const auto &b){return a[0] == b[0]?a[1] < b[1]:a[0] < b[0];});
        // 计算中心点的坐标
        double x=(double)(p[3][0] + p[0][0]) / 2,y=(double)(p[2][1] + p[1][1]) / 2;
        // 判断对角线是否相等,不相等则不是正方形
        if((pow(p[3][0] - p[0][0],2) + pow(p[3][1] - p[0][1],2)) != (pow(p[2][0] - p[1][0],2) + pow(p[2][1] - p[1][1],2))) return false;
        // 判断中心点与端点之间的连线是否垂直
        if((pow(p[0][0] - x,2) + pow(p[0][1] - y,2))*2 != (pow(p[0][0] - p[1][0],2) + pow(p[0][1] - p[1][1],2))) return false;
        return true;   
    }
};